URL和HTML编码
在呈现HTML页面时,有时候需要显示一些特殊的字符,例如”<”和”&”,因为它们是HTML专用字符,因此需要一些技巧.例如要想显示AT&T,在代码中必须写成AT&T。同样URL中的=,&,/等字符也为专用字符,所以如果需要在URL参数中使用它们,也必须对这些字符进行编,可以在%号后面加上字符的十六进制来替换这些有冲突的字符,例如将空格替换为%20.
下面举三个例子分别说明如何在HTML和URL中显示这些特殊字符,以及如何显示当前页面的源代码.
使用Server.HtmlEncode()函数
在第一个示例中,对于同样的字符串(注意其中含有一段浏览器可以识别的HTML标记)
"This HTML code <span class=/"redbolditalic/">should appear</span> with the tags invisible"
"This HTML code <span class=/"redbolditalic/">should appear</span> with the tags invisible"
我们采用两种方式(使用和不使用
HtmlEncode
对字符串编码)分别在Web页面中显示它们,看看效果有什么不同。显示效果如下图所示,可以看到如果未对字符串编码,浏览器在解析它的时候,如果遇到可以识别的HTML标记,就会按照呈现HTML的方式呈现它们,而不管它们是否是一个字符串的一部分。
浏览器的这种默认行为有时候并不是我们所希望的,假设我们就想在浏览器中显示
<span class=/"redbolditalic/">should appear</span>怎么办?很简单,我们只需要使用函数
HtmlEncode对它进行编码即可。
源代码如下:
//default.aspx
<%
@
Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!
DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns="http://www.w3.org/1999/xhtml">
<
head
runat="server">
<title>编码与解码
</title>
<link rel="stylesheet" type="text/css" href="StyleSheet.css" />
</
head
>
<
body
>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<asp:Literal ID="Literal1" Text="
未编码的HTML:"
runat="server"></asp:Literal>
</td>
<td>
<asp:Label ID="lblNoEncode" runat="server" Text=""></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Literal ID="Literal2" Text="
编码的HTML:"
runat="server"></asp:Literal>
</td>
<td>
<asp:Label ID="lblEncode" runat="server" Text=""></asp:Label>
</td>
</tr>
</table>
</div>
</form>
</
body
>
</
html
>
//default.aspx.cs
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
public
partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
String s = "This HTML code <span class=/"redbolditalic/">should appear</span> with the tags invisible";
lblNoEncode.Text = s;
lblEncode.Text = Server.HtmlEncode(s);
}
}
//StyleSheet.css
body
{
}
.redbolditalic {
color:red;
font-style: italic;
font-weight: bold;
}
使用Server.UrlEncode()函数
与
HTML编码类似,某些字符例如”=”, ”?”, ”&”都是
URL专用字符,如果希望在URL中传递这些字符也必须对它们进行编码。在下面的例子中我们希望通过URL传递“Hello! & How are you?”,这个字符串中包含特殊字符”?”和 ”&”,因此使用
UrlEncode函数对其编码。
//urlEncode.aspx
<%
@
Page Language="C#" AutoEventWireup="true" CodeFile="UrlEncode.aspx.cs" Inherits="UrlEncode" validateRequest="false" %>
<!
DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns="http://www.w3.org/1999/xhtml">
<
head
runat="server">
<title>UrlEncode</title>
</
head
>
<
body
>
<form id="form1" runat="server">
<div>
<%--
注意需要添加validateRequest="false"指令--
%>
<asp:HyperLink ID="HyperLink1" runat="server">HyperLink</asp:HyperLink>
</div>
</form>
</
body
>
</
html
>
//urlEncode.aspx.cs
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
public
partial class UrlEncode : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
String href, thisFile;
if (Request.QueryString["msg"] != null)
{
Response.Write(Request.QueryString["msg"]);
Response.End();
}
//
使用Request.ServerVariables["URL"]变量的值获取当前请求的URL.它把当前的URL和QueryString变量(msg)及值
//Hello! & How are you?
连接起来.代码在设置Hyperlink控件的NavigateURL属性前调用了Server.UrlEncode方法
//
进行编码.完全编码后的URL如下所示:
//http://localhost:2271/Encode/UrlEncode.aspx?msg=This+message+%3d+%3ch1%3eHello!+%26+How+are+you%3f%3c%2fh1%3e
thisFile = Request.ServerVariables["URL"];
//
故意在URL中包含了空格,虽然IE在处理包含空格的URL时,认为它是被正确编译的,但是在把它发送到其它浏览器时,仍然
//
需要用%20替换空格来测试web表单.
href = String.Concat(thisFile, "?msg=", Server.UrlEncode("This message = <h1>Hello! & How are you?</h1>"));
HyperLink1.NavigateUrl = href;
HyperLink1.Target = "_blank";
HyperLink1.Text = "Click me!";
}
}
如果不调用Server.UrlEncode函数,则只会显示
Hello!。这是因为它后面的专用字符&。
显示当前页面的源代码
在
ASP.NET AJAX Control Toolkit文档中有一个非常有特点的功能,它可以查看当前页面的源代码,它是怎么实现的呢?下面是显示文件代码的步骤:
1. 找到文件,创建一个
StreamReader实例以读取它的内容。
2. 读取文件的内容并对其进行编码
3. 显示在
Laebl上
源代码和结果如下所示:
//ViewCode.aspx
<%
@
Page Language="C#" AutoEventWireup="true" CodeFile="ViewCode.aspx.cs" Inherits="ViewCode" %>
<!
DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns="http://www.w3.org/1999/xhtml">
<
head
runat="server">
<title>查看源文件
</title>
</
head
>
<
body
>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnCode" runat="server" Text="View Code"
onclick="btnCode_Click" />
<asp:Button ID="btnHtml" runat="server" Text="View HTML"
onclick="btnHtml_Click" /><br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label><br />
</div>
</form>
</
body
>
</
html
>
//ViewCode.aspx.cs
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;
public
partial class ViewCode : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "Click the /"View Code/" button to view the code-behind code for this WebForm.<br>";
Label1.Text += "Click the /"View HTML/" button to view the HTML in the .aspx file.";
Label2.Visible = false;
}
protected void btnCode_Click(object sender, System.EventArgs e)
{
String currFile;
StreamReader sr;
//
获取当前aspx文件对应的code-behind文件的完整物理路径。它是从Request.ServerVariables集合中获取的,使用下面的
//
代码更为有效Server.MapPath(Request.ServerVariables["SCRIPT_NAME"]),原因是服务器必须为寻找匹配的关键字搜索
//
所有的Request集合,而不是只搜索ServerVariables集合.
currFile = Server.MapPath(Request["SCRIPT_NAME"]) + ".cs";
//
创建一个 StreamReader 读取内容。
sr = File.OpenText(currFile);
// HtmlEncode
内容并放在Label2中。
Label2.Text = "<h3>Code-behind code for the file " + currFile + "</h3><pre>" + Server.HtmlEncode(sr.ReadToEnd()) + "</pre>";
Label2.Visible = true;
sr.Close();
}
protected void btnHtml_Click(object sender, EventArgs e)
{
String currFile;
StreamReader sr;
//
获取当前aspx文件
currFile = Server.MapPath(Request["SCRIPT_NAME"]);
//
创建一个 StreamReader 读取内容
sr = File.OpenText(currFile);
// HtmlEncode
内容并放在Label2中。
Label2.Text = "<h3>HTML code for the file " + currFile + "</h3><pre>" + Server.HtmlEncode(sr.ReadToEnd()) + "</pre>";
Label2.Visible = true;
sr.Close();
}
}
后记:
本文中的所有示例都来自《ASP.NET与C#从入门到精通》,作者A.Russell Jones,电子工业出版社出版。此书中的内容虽然是基于ASP.NET(ASP.NET 2.0的上的一个版本)的,与《Programming ASP.NET》 3
rd相比,此书对重要概念的解释要细致深刻的多。而《Programming ASP.NET》则属于入门书,手把手教你如何建立一个ASP.NET应用程序,每一步都很详细,但是对重要的概念则点到为止,不能深入。