设为首页收藏本站喵玉殿官方微博

 找回密码
 少女注册中
搜索
查看: 12062|回复: 22

[提问其他] 【SOS】UWP应用开发学习、记录与求助

[复制链接]
发表于 2015-12-15 20:11:41 | 显示全部楼层 |阅读模式
  嗯,最近希望学习微软的UWP(通用应用)编程,所以尝试一下做一个猫王论坛的客户端。
  然而……前途渺茫的感觉啊……现在UWP的资料很少见呢,而之前WP的东西又有很多不在支持了,所以本来感觉很简单的地方折腾了好久都没有成效。总之,在这里留下一个帖子,慢慢的来记录学习与开发的过程,同时希望各位有开发经验或者有好点子的大神们指点迷津。
  哦,对了。因为我本身只学过C++,而且学艺不精。所以本篇帖子会出现各种不可预料的搞笑情节。例如:
  1:基本概念不清晰,名词张冠李戴
  2:抓不住问题重点,在莫名其妙的地方纠结起来
  3:我想不出更多了……

  嘛,总之大家多包涵,遇到错误的地方请直接指出。

  嗯,这两天面临的第一个挑战就是论坛返回的HTML是GBK编码的。
  下面我写了一个简单的示例程序,说明一下我所遇到的问题。示例程序以及相关文件会在帖子最后放出下载,各位大神有兴趣的话,请务必帮帮我吧,如果发现描述不清或者缺少的东西,请提出来,我会补上。如果联系我不方便的话,请加QQ:923657882

  以百度为例好了,百度的网站就是UTF-8编码的
   001 百度 utf-8.jpg
  而咱们的喵玉是GBK
   002 喵玉 gbk.jpg
  嗯,所以在得到返回的数据流时,就得到了很无语的现象——中文全是乱码

  我在工程文件中的MainPage.xaml.cs文件中实现了一些功能,包括输入一个网址,向网址发送HTTP请求,然后得到返回的数据流。
  我在MainPage.xaml.cs的第54行放一个断点。先用百度的首页(www.baidu.com)作为示例。运行程序,在输入框里输入URL,然后点获取
   003 百度 输入.jpg
  这之后,会运行到断点的地方。这里的stream大概包含了返回来的数据流
   004 stream.jpg
  然后运行下一句。
  reader.ReadToEnd()方法是将reader里面包含的数据流从头到尾传递给string
  我们来看看百度首页传过来的是怎样的html
  在监视窗口里看一下content的值
   005百度 string.jpg
   006 百度 content.jpg
  可以看到,这里是正常显示了中文的
  再试一下喵玉
007 喵玉 content.jpg
  所有中文都是乱码

  以上,便是问题的描述。那么我希望解决的问题是什么呢?
  因为不能够更改服务器,所以在客户端上,不管用怎么样的形式,只要得到正常的中文代码就好。
  哦,为了保护喵玉的服务器不受到我无心之失的影响,我临时另搭了个测试用的论坛,版本号和猫王是一样的,请使用这个做实验http://windwhisper.club

  这个问题我目前仍未解决,那么接下来说一些我的分析。这些分析有的有用,有的或许没用,嘛,总之我把我想过的尽量全写出来,希望能够抛砖引玉,我觉得最后希望的办法,写在了最后

  1:这个问题我认为出在54行的StreamReader(stream)这个方法上。这一个方法默认使用UTF-8来读取数据流。所以GBK的数据流就被读成乱码了。我找了找解决办法,可是发现微软官方是不支持GBK的。
008streamreader重载.jpg
  StreamReader有很多重载,大略查了一下msdn的开发文档,好像如图第三个重载,是可以按照指定的编码来读取的,可是Encoding支持的编码很少,并没有GBK
009 encoding.jpg
  如图所示,第一个是最简单的ASCII,然后林林总总的列了不少,并没有GBK或者GB2312
  可是我发现最后一个WebName好像是可以由用户自己来写的虚函数。
  可是最终我也没弄明白这个是干什么用的

  再说说另一个发现
  当程序运行到第55行时,我观察了一下reader,他是一个StreamReader类的变量,发现了很多莫名其妙的地方。
  首先看我用红框圈起来的地方。reader.CurrentEncoding的静态成员里,有个非公共成员列表,这里面列出了一大堆编码的名字和代号,而我梦寐以求的GB2312就大喇喇的躺在那里。可是……这个是什么意思,又能不能用呢?
  然后是黄色圈起来的地方,reader.CurrentEncoding.EncodingName里,属性值是UTF-8,这会不会表示了reader里的内容是UTF-8编码的呢?如果是这样的话,这证明在这之前,我们的数据流就已经惨遭毒手了。
  然后又出现了reader.CurrentEncoding.WebName,刚才出现过WebName相关的函数,我不知道这两者之间有什么联系。或许重写一个虚函数就能够使用gb2312了?
010 reader.jpg

  最后要说的,是我觉得比较靠谱的解决方案。来自这两篇帖子
  http://www.cnblogs.com/xuesong/archive/2011/12/15/2288754.html
  http://www.cnblogs.com/yffswyf/p/4826207.html
  第一个帖子讲了如何在以前的旧环境里解决gb2312的问题,里面描述了三种方法,好像第一种比较适合。可是这些方法在UWP里已经不支持了。
  第二个帖子好像解决了第一篇帖子第一个方法不能继续使用的问题,然而,我没看懂……
  嗯,我个人倾向于朝着这个方向上努力去解决gb2312的问题。下面我来说一下前辈们的方法出了哪些问题。
  首先,按照第一篇帖子的办法,在工程里新建gb2312文件夹,把两个.bin和一个.cs全放进去。然后设置两个.bin的生成操作为“嵌入的资源”,.cs文件生成操作设置为“编译”(我这里貌似默认就是编译,不用设置)
  然后本以为可以正常使用的我发现,第56行报错
011 gb.jpg
  好像是因为原本的API不在支持之类的原因
  总之,失败了

  然后按照第二篇帖子修改这个问题。我就不说我怎么改的了,因为我压根儿不知道怎么改。可是,我觉得这个方法应该是最简单有效的,不知道有没有能看懂第二篇帖子的大神呢?总之,这里是一个苦苦挣扎着的咸鱼发出的SOS信号,我会继续探索下去,也希望能够得到有力的帮助,嗯就这么多了。下次再接着记录好了。

工程文件下载链接: http://pan.baidu.com/s/1dEgW63Z
密码: qx4k


发表于 2015-12-16 00:15:22 | 显示全部楼层
对了其实。。。可以单独弄个服务器来处理转码。。。asp.net总能支持GBK吧。。。

点评

其实当初做安卓的时候已经修改过后端插件了(不清楚php能不能转码  发表于 2015-12-16 16:33
我觉得还是别动服务器比较好,我害怕咱一不小心搞错把数据搞丢之类的。嘛,我尽量在客户端这里下功夫吧,如果再遇到实在解决不了的问题,咱们再考虑改服务器的事情吧  发表于 2015-12-16 15:03
就放论坛后端啊  发表于 2015-12-16 12:16
单独弄个服务器成本太高了吧,简直壕无人性  发表于 2015-12-16 10:06
回复

使用道具 举报

 楼主| 发表于 2015-12-22 20:14:57 | 显示全部楼层
  嗯,上次的问题虽然看起来很困难,然而其实是搞错方向了。
  当获取过来的HTML文件已数据流的形式读过来的时候,会牵扯到编码问题。
可是当做字符串就好了
  就这么简单

  不过上次的问题得到了两种解法,一种是我原先的路子,使用那个工程文件,引用的时候使用ms-appx这个API,当然,大神说了以后,我并没有听懂

  还有一个解决办法是使用http请求筛选器——HttpBaseProtocolFilter
  这个办法比上一种简单,只要设定好http的头就好了。具体的函数不再写出了,因为毕竟两种方法都是比较麻烦的

  简单说一下最后的解决办法,使用HttpClient类进行Get请求,使用GetStringAsync方法,这样返回的便是字符串,不用考虑编码的问题。
  额……想想我搞了3天的毛病竟然辣么简单……为什么我的眼里常含泪水,因为我渣的深沉

  这次进度还算不错,我虽然不太会抓包,不过乱抓一起也零零散散把必要的东西找出来了
  可是还是不知道具体怎么做啊?
   问题主要围绕cookie和登录,有一下几点:
1. 没登录的用户要不要cookie?
2. Cookie在登录前记录还是登陆后记录?
3. 登录怎么搞啊?
4. Cookie在登录后用不用变之类的……
5. Post的数据用不用编码,加密之类的。

   嗯,我还是说说我这两天过河摸的石头好了

   感觉Cookie大约是在登录前就有的,每次http请求,都会给新的请求者生成一个新cookie,cookie里面的值很奇妙,看不懂,也不知道有啥用,怎么用
   所以……登录前大概会有一个cookie,然后用户登录成功,系统或许会发一个新的cookie,或许就这个cookie一直用下去了,嗯,明天再对比一下好了,感觉应该会换新的
   登录的话,填一个表单,然后post出去,地址也找到了,可是在默认的论坛上实验后发现不行……究竟怎么不行我也不知道,只好明天接着搞了。而猫王的论坛比默认的论坛多了一个步骤,会有验证码,验证码最开始很头疼,因为有很多莫名其妙的数据,不过后来还是发现其中奥妙了,以后有时间再详解
   我的书上写了cookie的设置,不过我没看明白究竟是客户端设置还是服务器设置。感觉应该是服务器设置cookie,和客户端没有关系,客户端要做的,大约只是请求然后存储cookie,在每次http请求时带上cookie。


   嗯,接着考虑一下应用的大体框架。
   其实感觉也没什么好考虑的,UWP的东西全长一样,一堆方块儿堆一起就是了。每个页面的布局尽量自适应屏幕,不过自适应是UWP的强项,感觉应该不会有太多问题。
   如果不考虑客户端的登录与回复问题【那就基本上没剩什么问题了吧】,大约现在就可以设计UI开始做了
   总之,借鉴一下现在安卓的样式,加进一些wp风格就好了。我很中意wp的枢轴控件和全景视图控件,两种都很漂亮,等彻底搞懂网络了就去做UI
   或者我们可以使用迭代开发,先搞出一个可以浏览用的客户端,然后在考虑加入登录与回复功能2333333


点评

貌似HttpClient可以自动托管Cookie,也就是说,不用考虑cookie的问题。 一个被巨硬伤透了心的人所留  发表于 2016-2-2 17:50
回复

使用道具 举报

 楼主| 发表于 2016-1-1 21:30:27 | 显示全部楼层
  今天出现的蜜汁问题是使用HttpClient获取到的网页HTML代码不全。
  
  这是我使用的代码,很简单,就这么几句
  
   01.jpg
  
  设置网址,然后使用httpclient接收返回的HTML,然后发现返回的不全……
  
   02.jpg
  在红框圈中的地方里(大约200多行的地方),本来应该有大段信息才对的,在浏览器上查看源代码,能够得到正确的HTML,然而自己写出来的就会少大段信息。
  我想,大概是因为论坛的服务器使用了gzip将HTML压缩的原因。
  可是……我没找着解决办法,或者问题并不在于页面被压缩。
  
  我抓一个包来举个例子好了。
   03.jpg
  这个是get请求的数据包,http头里面能够看到Accpet-Encoding:gzip,deflate
  这应该意思是请求使用gzip压缩后的html文件
  
   04.jpg
  这个是返回的html的数据包
  我们在html头里也能看到Content-Encoding:gzip
  这大概表示了这个页面是被gzip压缩过的吧。
  
  
  所以,该怎么才能获得正确的html呢,大概需要在http头里设置写什么吧,然而……找不到资料啊啊啊啊


回复

使用道具 举报

 楼主| 发表于 2016-1-2 14:13:06 | 显示全部楼层
VS大坑......
自带的文本显示工具,对于长文本不能完全显示
所以.......其实单独使用httpclient就好了,gzip是本身可以解压的

不过今天折腾了一下也有好处,知道了http的头应该怎么设置
使用HttpBaseProtocolFilter可以轻松设置http请求的头,而且设置的方法难以置信
本来以为应该调用函数,然后设置
结果发现随便写个字符串就能当做http头的属性,属性值也可以随便填
还真是随性的方法啊

嗯,综合看看的话,好像网络部分的研究已经差不多了。
开始试着做一个雏形出来好了
回复

使用道具 举报

发表于 2016-1-4 16:59:19 来自手机 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复

使用道具 举报

 楼主| 发表于 2016-1-9 13:09:51 | 显示全部楼层
吼吼吼吼在32与Ofz两位大大的指点下,使用了手机版的api

登录时使用手机版登录uri得到了解决
01.jpg

最让我激动的是终于能够获得干净简单的json数据了
本来我以为插件提供的API是分操作系统的,只能供给Android和IOS用,后来发现和操作系统半毛钱关系都没有啊
既然没关系,为毛discuz官方的介绍里还强调支持Android和IOS,不是很懂腾讯

本来我都快放弃了,想要直接使用html来写,自己想办法把html里有用的信息剥出来。
看来差点重造轮子,还是用别人的轮子舒服啊啊啊
回复

使用道具 举报

 楼主| 发表于 2016-2-2 17:37:26 | 显示全部楼层
C#中如何使用MD5加密呢。
挺简单的,你需要引入两个头文件

using System.Security.Cryptography;
using System.Text;

然后
byte[] result = Encoding.Default.GetBytes(this.tbPass.Text.Trim());    //tbPass为输入密码的文本框
MD5 md5 = new MD5CryptoServiceProvider();
byte[] output = md5.ComputeHash(result);
this.tbMd5pass.Text = BitConverter.ToString(output).Replace("-","");  //tbMd5pass为输出加密文本的文本框


嗯,这么着大概就成了。

回到UWP里
不出所料的,巨硬的UWP并不包含System.Security.Cryptography头文件
嗯,没关系,办法总是有的

引入这三个头文件
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

然后代码这么写

//可以选择MD5 Sha1 Sha256 Sha384 Sha512
string strAlgName = HashAlgorithmNames.Md5;

// 创建一个 HashAlgorithmProvider 对象
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);

// 创建一个可重用的CryptographicHash对象           
CryptographicHash objHash = objAlgProv.CreateHash();

string strMsg1 = "这是一段待加密的字符串";
IBuffer buffMsg1 = CryptographicBuffer.ConvertStringToBinary(strMsg1 , BinaryStringEncoding.Utf16BE);
objHash.Append(buffMsg1);
IBuffer buffHash1 = objHash.GetValueAndReset();
string strHash1 = CryptographicBuffer.EncodeToBase64String(buffHash1);


可是,这只适用于16位的MD5加密,因为ConvertStringToBinary方法的第二个参数BinaryStringEncoding只有三个属性,两个16位,一个8位
事实上大部分时候使用的是32位MD5加密呀
所以......巨硬官方办法解决不了,只好看大神了
MD5Create.rar (4.2 KB, 下载次数: 237)

这个cs文件是某位大神写的
也就是说从新实现了MD5的加密
这个方法多简单呢,简单到把这个文件添加到工程后,连实例化都不需要
因为是静态方法,所以直接使用就好了

MD5.GetMd5String(string str);

str是你想要加密的字符串
返回的就是加密完成的

嗯,以上

回复

使用道具 举报

 楼主| 发表于 2016-2-7 14:06:17 | 显示全部楼层
  日了狗。
  UWP、WP、WPF是坑。
  深坑。
  无底坑。
  这一系列框架提供了两种有可能支持图文混排的控件。
  一个叫richtextblock,一个是webview
  对于论坛这种排版有点复杂的网页结构,微软的框架并没有合适的控件。
  Richtextblock虽然支持图文混排与数据绑定,可是他的格式是固定的,也就是说是图片的地方只能显示图片,是文字的地方只能显示文字,而不能根据实际需要显示。
  另一个webview能够解析html,能够显示图片,可是在listview中不能够数据绑定。而且,webview不能够自适应屏幕大小,他的大小是固定的。
  结论就是没一个是能用的。
  我此刻体会到了所有UWP、WP开发者深深的怨念,怪不得微软应用商店基本没应用,有的也就是那么几个渣的不行的。
  臣妾做不到啊!!!!
  回头看了看应用商店的应用,能够支持图文混排的,大概是这个样子的
  
   01.jpg
  果壳的这种一看就是一个webview,毫无技术含量
  他并没有类似论坛帖子一层一层的结构,只要一个webview就好,而论坛则需要把webview嵌在listview里,显示成一层一层的

   02.jpg
  NGA的能够支持图文混排,而且是一层一层的,初看的时候很像我所希望的listview嵌webview,可是后来发现这东西不能够增量加载,需要手动翻页。所以,这大概还是一个webview。
  到这里,我只有两种解决方案,一种,和他们一样,搞成一个webview。
  做成一个webview的话,首先需要根据服务器返回的json在本地生成html,这不是坑的地方,坑的地方在于,微软的webview在数据绑定的情况下,不能够根据字符串显示内容,根据字符串显示内容的话,没法数据绑定。用webview的方法是把生成的html写入本地文件,在让webview自己从本地文件读取。
  这他喵有效率???效率两个字怎么写!!
  另一个办法我上午在尝试,listview里嵌listview。把一个帖子的一个回复按图片和文字分成好几段,在分别显示出来。
  这办法我没搞成。
  我也不知道问题出在哪里,我试着新开了小的工程,测试listview的嵌套是否可行。
  可行。
  可是在nyasama的项目上就无法正常显示。放了断点一条条看过去,也不知道问题出在哪里。
  迷之问题。
  嗯,所以还是用listview先做个仅有文字的版本好了,等到学一点css,再去尝试使用webview。

点评

澶х害鍙?互闂?棶ofz鐨勮В鍐虫  发表于 2016-2-7 21:12
回复

使用道具 举报

发表于 2016-10-23 10:35:36 | 显示全部楼层
最近买了个win10的手机,想问进度如何了,还在做吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 少女注册中

本版积分规则

合作与事务联系|无图版|手机版|小黑屋|喵玉殿

GMT+8, 2025-10-31 03:39

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表