ASP.NET 中的字符编码问题,一般会有两个场景:

  • HTML 编码:一般是动态显示 HTML 字符或标签,写法是:HttpUtility.HtmlDecode(htmlString)Html.Raw(htmlString) 等。
  • URL 编码:一般是作为 URL 的一部分,写法是:HttpUtility.UrlDecode(urlString)Uri.EscapeDataString(urlString) 等,具体的流程就是上面的图,因为涉及到 URL 及请求处理,所以对于一些特殊字符的处理,要格外小心。

HTML 编码

在 ASP.NET 中,这也是我们使用最多的一种,流程很简单,把 HTML 标签内容存储到数据库,然后再获取出来展示,在存储数据库之前,一般会进行 HTML 编码,因为 MVC 在展示的时候,会对字符型的 HTML 做保护处理,所以要对 HTML 编码后的字符,再进行转码。

MVC 展示字符一般会有两个场景:

  • 显示 HTML 字符(比如 < > 等特殊字符)。
  • 显示 HTML 标签(把字符作为 HTML 标签显示)。

我们来看一个代码示例:

1. @HttpUtility.HtmlEncode("&lt;span&gt;test&lt;/span&gt; ")
<br />
2. &lt;span&gt;test&lt;/span&gt;
<br />
3. @("<span>test</span>")
<br />
4. @HttpUtility.HtmlDecode("&lt;span&gt;test&lt;/span&gt; ")
<br />
5. @HttpUtility.HtmlDecode("<span>test</span>")
<br />
6. @Html.Raw("&lt;span&gt;test&lt;/span&gt; ")
<br />
7. @Html.Raw("<span>test</span>")

显示结果:

简单总结:

  • HttpUtility.HtmlDecode 和 Html.Raw 作用并不相同。
  • HttpUtility.HtmlDecode 仅仅是对编码后的 HTML 进行转码,效果和第三点一样。
  • Html.Raw 是对原字符进行直接输出,是什么就是什么。
  • HttpUtility.HtmlDecode 一般会用在显示 HTML 字符。
  • Html.Raw 一般会用在显示 HTML 标签。

URL 编码

关于 URL 编码,说简单也简单,说复杂也很头疼,简单列举下几种常用方式:

  • HttpUtility.UrlEncode:最常用的一种,一般是对参数进行编码,但对于一些特殊字符不适用,而且 URL 显示不友好。
  • Uri.EscapeDataString相关博文,处理一些特殊字符(+),需要在 web.config 中配置 allowDoubleEscaping 为 true。

在最上面图中,一共有五步流程,但都是问号,下面我用一个示例,来说明这五步具体该如何操作,示例 URL:

http://www.cnblogs.com/xishuai/tag/蟋蟀·博客园&URL 空格<>test

处理步骤:

  1. 从界面提交到应用服务器,不进行转码,值为:蟋蟀·博客园&URL 空格<>test。
  2. 从应用服务器提交到数据库,不进行转码,值为:蟋蟀·博客园&URL 空格<>test。
  3. 从数据库获取到应用服务器,不进行解码,值为:蟋蟀·博客园&URL 空格<>test。
  4. 从应用服务器展现到地址栏,进行转码(Uri.EscapeDataString),值为:蟋蟀·博客园%26URL%20空格<>test。
  5. 从浏览器响应到应用服务器,不进行解码,值为:蟋蟀·博客园&URL 空格<>test。

在上面第4、5步的时候,URL 会变为:

http://www.cnblogs.com/xishuai/tag/%E8%9F%8B%E8%9F%80%C2%B7%E5%8D%9A%E5%AE%A2%E5%9B%AD%26URL%20%E7%A9%BA%E6%A0%BC%3C%3Etest

这个不需要你进行任何操作,从浏览器到服务器、从服务器到浏览器,这个过程中,URL 会进行自动转码和解码,比如你在 Action 中获取 Tag 值,并不需要使用 HttpUtility.UrlDecode 解码操作。

不过,针对一些特殊的字符,因为第5步是请求操作,IIS 会对请求进行一些检测,web.config 还需要进行下面配置:

<system.web>
<compilation targetFramework="4.5" />
<httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="" /><!--添加的配置-->
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<security>
<requestFiltering allowDoubleEscaping="true"/><!--添加的配置-->
</security>
</system.webServer>

总的来说,URL 特殊字符编码问题,只使用 Uri.EscapeDataString,然后 web.config 进行如上配置就可以了。

///2015-6-2更新:

如果 URL 包含“.”参数,如:www.cnblogs.com/xishuai/tag/....../,则会出现“404”错误(IIS 截获了,没有到应用程序),但并非是 HTTP 状态码,解决方式:

<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" /><!--添加的配置-->
</system.web>

ASP.NET 字符编码的那些事的更多相关文章

  1. 字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8

    原作者:阮一峰(ruanyifeng.com),现重新整理发布,感谢原作者的无私分享. 1.引言 今天中午,我突然想搞清楚 Unicode 和 UTF-8 之间的关系,就开始查资料. 这个问题比我想象 ...

  2. (转载)字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8

  3. 关于Unicode,字符集,字符编码,每个程序员都应该知道的事

    关于Unicode,字符集,字符编码,每个程序员都应该知道的事 作者:Jack47 李笑来的文章如何判断一个人是否聪明?中提到: 必要.清晰.且准确的概念,是一切思考的基石.所谓思考,很大程度上,就是 ...

  4. 【转】关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)

    转载地址:http://www.imkevinyang.com/2010/06/%E5%85%B3%E4%BA%8E%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%EF%BC ...

  5. 关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)

    字符编码的问题看似很小,经常被技术人员忽视,但是很容易导致一些莫名其妙的问题.这里总结了一下字符编码的一些普及性的知识,希望对大家有所帮助. 还是得从ASCII码说起 说到字符编码,不得不说ASCII ...

  6. Python:字符编码详解

    相关文章 Python中文编码问题:为何在控制台下输出中文会乱码及其原理 1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Informati ...

  7. Python 字符编码 zz

    http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 1. 字符编码简介 1.1. ASCII ASCII(American Stan ...

  8. Python字符编码详解

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...

  9. 【转】Python字符编码详解

    转自:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 1. 字符编码简介 1.1. ASCII ASCII(American S ...

随机推荐

  1. mac安装虚拟机

    1. 安装VirtualBox 2. 新建,按照步骤一步步选择 3.安装系统镜像 xp_sp3_74070.iso CN_WIN7_SP1_X64_33in1_V1.2.iso 设置磁盘分区等 4.V ...

  2. host Object和native Object的区别

    Native Object: JavaScript语言提供的不依赖于执行宿主的对象,其中一些是内建对象,如:Global.Math:一些是在脚本运行环境中创建来使用的,如:Array.Boolean. ...

  3. android studio/Intellij idea之proguard实践

    默认情况下,build->Gene Signed APK 反编译后发现,没有混淆... 多次爬stackoverflow才搞定这个问题: 首先 build variants这里由debug设置为 ...

  4. BOM对象有哪些:

    BOM对象有哪些: 1.window对象 ,是JS的最顶层对象,其他的BOM对象都是window对象的属性: 2.document对象,文档对象: 3.location对象,浏览器当前URL信息: 4 ...

  5. C语言的傻瓜式随笔(一):嵌套循环-程序结构

    循环语句的嵌套 一个循环结构内可以含有另一个循环,称为循环嵌套,又称多重循环.常用的循环嵌套是二重循环,外层循环称为外循环,内层循环称为内循环. ---------不知道哪来的基础概念 这是本宝宝的第 ...

  6. SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/D:/MyEclipseWorkSpace/Emps/WebRoot/WEB-INF/lib/slf4j-nop-1.5.6.

    错误的是HQL语句,注意写类名属性名无误,条件无误.

  7. Windows Azure一些小技巧集合

    我最近做了一个Windows Azure上面的项目,自己在做的过程中遇到了很多问题.有的是我自己摸索解决,有的是到网上寻找零碎的信息结合起来解决的.我感觉应当把某些解决方法集中一下,方便我以后查阅,也 ...

  8. String驻留带来的危害

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com   前段时间接手了一个项目优化工作,在同等场景下内存使用从4G降低到200M.   项目是将实体序列化成字符串存入 ...

  9. Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint

    <Windows Azure Platform 系列文章目录> 请注意: - Azure不支持增加Endpoint Range - 最多可以增加Endpoint数量为150 http:// ...

  10. ORA-12899: value too large for column (actual: 27, maximum: 20)

    导入数据时报错以下错误,这是因为原来的数据库是GBK的,每个汉字两个字节,但新数据库是UTF-8的,每个汉字是三个字节,导致超过长度了. ORA-12899: value too large for ...