解决服务器返回JSON数据中文乱码问题
还是编码的问题.
下午试了一下谷歌搜索的 REST 服务, 接口是 "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=<search item>, 过程也很简单: 将你要搜索的内容经过 UrlEncode 之后代替<search item>, 然后发出一个 GET 请求, 就应该得到该搜索内容的 JSON 数据. 比如我搜索 "Create Chen", 在浏览器中可以看到返回如下数据:
{"responseData": {"results":[{"GsearchResultClass":"GwebSearch","unescapedUrl":"http://www.cnblogs.com/technology/","url":"http://www.cnblogs.com/technology/","visibleUrl":"www.cnblogs.com","cacheUrl":"http://www.google.com/search?q\u003dcache:wymiOeNCuYMJ:www.cnblogs.com","title":"\u003cb\u003eCreate Chen\u003c/b\u003e - 博客园","titleNoFormatting":"Create Chen - 博客园","content":"posted @ 2011-05-26 15:57 \u003cb\u003eCreate Chen\u003c/b\u003e 阅读(1206) | 评论(30) | 编辑 \u003cb\u003e...\u003c/b\u003e posted @ 2011-05-22 20:49 \u003cb\u003eCreate Chen\u003c/b\u003e 阅读(1781) | 评论(26) | 编辑
...省略以下内容...
展示上一段的目的是为了说明在浏览器里, 数据包含中文的话, 还是显示正常的, 原因很简单: 我浏览器设置的默认编码就是 Unicode(UTF-8), 当然能正确显示中文.
为了更好的展示数据, 我按照<Programming ASP.NET 3.5>里将在程序中获得的 JSON 数据序列化了一下, 没想到总是在序列化的时候出错, 只有搜索结果不包含中文的时候才运行正常. 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //... //GoogleSearchResponse的一些构造 //... protected void btnSearch_Click( object sender, EventArgs e) { WebClient wc = new WebClient(); Response.Write(wc.Encoding.ToString()); wc.Headers.Add(HttpRequestHeader.Referer, Request.Url.ToString()); string url = string .Format( "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={0}" , Server.UrlEncode(txtSearchFor.Text)); var json = wc.DownloadString(url); GoogleSearchResponse sechResponse = null ; using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) { DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer( typeof (GoogleSearchResponse)); sechResponse = jsonSerializer.ReadObject(ms) as GoogleSearchResponse; } StringBuilder sb = new StringBuilder(); foreach (GoogleResult res in sechResponse.responseData.results) { sb.AppendFormat( "<a href='{0}'>{1}</a><br />" , res.unescapedUrl, res.title); } lblResults.Text = sb.ToString(); } |
经过调试发现在代码高亮的那一行, json字符串已经是乱码了. 因此我查看了 WebClient 的 DownloadString 方法:
This method retrieves the specified resource. After it downloads the resource, the method uses the encoding specified in the Encoding property to convert the resource to a String. This method blocks while downloading the resource. To download a resource and continue executing while waiting for the server's response, use one of the DownloadStringAsync methods.
前面两句说在下载到资源 (应该是 Byte[]) 后, 这个方法将会调用默认的编码方式将资源转化成 String. 好吧, 我来看看默认的编码方式是不是 UTF-8. 往往默认的编码方式是由操作系统和地区决定的, 在我的机器上测试后得知默认的编码方式不是 UTF-8, 是 System.Text.DBCSCodePageEncoding, 尽管编码方式不是 UTF-8, 但除了中文集字符, 这种编码方式确实还能识别出 Unicode 类型的编码, 前提是文件开头要有 BOM 信息, 关于能从 BOM 中获得哪些信息, 如下:
Unicode 0xFF, 0xFE
BE-Unicode 0xFE, 0xFF
UTF8 0xEF, 0xBB, 0xBF
就是这样的一个对应关系, 但我发现服务器返回的 JSON 数据并没有这样的 BOM 信息:
因此, 我需要在程序中设置一下 WebClient 的 Encoding 属性, 将它设为 Encoding.UTF8, 运行正常.
但回过头来看看, 程序似乎在 DownloadString 方法中将下载到的 Byte[] 转成一个 String, 紧接着又将这个 String 转换成 Byte[] 存进内存中, 可以直接调用 DownloadData 方法的, 将 DownloadData 方法下载到的数据直接存储到内存中, 然后再做进一步的序列化处理, 这样就省去了两次类型转换的操作.
关于编码, 前几天还看到了一个笑话, 也不知道是真的还是假的:
以Windows中文版为例。从英文版移植到中文版,并不只是翻译菜单那么简单,许多源代码都得重新改写。比如Word里打完一行字会自动换行,可英文是单字节的,中文却是双字节,一个“好”字,就很可能“女”在上一行末尾,“子”却到了下一行开头。——唐骏 <我的成功可以复制> P89
作者:Create Chen
出处:http://technology.cnblogs.com
说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库