在ASP.NET中实现Url Rewriting

4.处理回送数据
  
    如果要重写的网址上包含有服务器端Web Form并执行数据回送,当该Web Form回送数据时会暴露出真实的网址,也就是说,当用户访问/Products/Baverage.ASPx时,浏览器上地址栏显示的也是/Products/Baverage.aspx,但是实际上是访问/ListProdutsByCategoryID.aspx?CategoryID=1的内容,如果ListProductsByCategoryID.aspx页面执行了数据回送的话,用户被数据回送定向给原始的/ListProductByCategoryID.aspx?CategoryID=1页面上,而不是/Products/Baverage.aspx页面。这虽然不是什么大问题,但是用户会觉察到点击一个按钮时网址发生了的变化,这也许会令人不安,因为如果出于网址安全的角度来说,直接把真实的网址暴露出来了。
  之所以发生这种现象的原因是当Web Form在呈现之时就明确地设置其action属性为当前Request对象中文件路径的值。当然,在Web Form呈现之时,从/Produts/Baverage.aspx到/ListProductsByCategoryID.aspx?CategoryID=1的网址重写就已经执行完毕了,这意味着Request对象所汇报的是当前用户所访问的地址是/ListProductsByCategoryID.aspx?CategoryID=1。这么看来,只需让该服务器端表单在呈现之时不呈现action属性即可解决问题了。(对浏览器来说,如果不设置action属性的话,那么在提交的时候将使用其默认值。)
  
    然而不幸的是该Web Form不会允许你指定action属性,也不会允许你通过设置一些属性来达到禁用呈现action属性的目的。得自行继承System.Web.HtmlControls.HtmlForm这个类,并重载该类的RenderAttribute()方法,明确指出该类不呈现acton属性。
  
    感谢继承这个强大的功能,使得我们很简单就获取了HtmlForm这个类下所有的功能定义,只需少量几行代码就达到所需目的,完整代码如下所示:
  
  namespace ActionlessForm
   {
   public class Form:System.Web.UI.HtmlControls.HtmlForm
   {
   protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer)
   {
   writer.WriteAttribute("name",this.Name);
   base.Attributes.Remove("name");
  
   writer.WriteAttribute("method",this.Method);
   base.Attributes.Remove("method");
  
   this.Attributes.Render(writer);
   base.Attributes.Remove("action");
   if (base.ID!=null)
   {
   writer.WriteAttribute("id",this.ClientID);
   }
   }
   }
  }
  
    对RenderAttributes()方法重载的代码包含了原类HtmlForm的RenderAttributes()方法全部的代码内容,只是简单地去掉了设置action属性这一节。
  
    当创建并编译了这个类后,将其添加到引用目录即可在该ASP.NET Web应用程序中使用。为了将原有HtmlForm类替换,只需简单地在页面顶部添加下列代码:
  
   <% @ ReGISter TagPrefix = " skm " Namespace = " ActionlessForm " Assembly = " ActionlessForm " %>
  
    然后将<Form runat=”server”>标签替换为
  
  <skm:Form id="Form1" method="post" runat="Server">
  
    并将结束标记</Form>替换为
  
  <skm:Form>
  
    你可以查看该文档相关下载中的ListProductsByCategoryID.aspx文件中的自定义Web Form,该下载已经提供了完整的Visual Studio.net项目文件包。
  
    注意:如果你打算进行网址重写的地址不执行数据回送,则没有必要使用该自定义Web Form的类。
  
    创建真正“隐蔽”的网址
  
    上一节简单网址重写的示例展示了如何通过新的网址重写规则来轻松地配置网址重写引擎,本节将通过出众的正则表达式来展示网址重写的强大威力。
  
    时下正在流行Blog,很多人都拥有一个自己的Blog。不论你是否对Blog感到陌生,他们正在不断地更新自己的Blog页面,这些页面就像一个个人日记本一样。大多数Bloger只是简单地记录每天发生的事情,也有一些聚焦于某一主题,比如影评、球迷组织、电脑技术等。
  
    Blog可以在任何地点由作者进行更新,更新次数可以是一天多次,也可以是一周一两次。在Blog页面上只显示最近10条更新,但事实上所有的Blog软件都提供了存档记录,访客可以阅读其历史记录。有了“隐蔽”的网址,Blog应用程序将变得更加强大。假定你通过/2004/02/14.aspx来查询自己的Blog上的文章,你会为阅读到2004年2月14日的Blog感到惊讶吗?此外你可能为了访问2004年2月所有的Blog而将该地址裁减为/2004/02/,要访问2004年所有的Blog,你可能会试着去访问/2004/。
  
    在维护一个Blog的时候,如果将这种具有“隐蔽性”的网址提供给用户将会更好。实际上很多Blog引擎都提供了这种网址重写的功能,现在来看看这些是如何通过网址重写实现的。
  
    首先,我们需要一个页面能够分别按照年、月、日分别显示Blog的内容。假定现在已经做好了一个页面文件ShowBlogContent.aspx,它能分别获取年、月、日的查询参数,要查看2004年2月14日所发的帖子,我们可以访问/ShowBlogContent.aspx?year=2004&month=2&day=14,要浏览2004年2月的数据可以访问/ShowBlogContent.aspx?year=2004&month=2,要查询2004年所有数据可以访问/ShowBlogContent.aspx?year=2004。(在下载文件中提供ShowBlogContent.aspx源代码。)
  
    然后,当用户访问/2004/02/14.aspx时,我们需要将他访问的网址重写到/ShowBlogContent.aspx?year=2004&month=2&day=14上。这里需要制定三条网址重写规则:当指定访问年月日时、当指定访问年月时和当指定访问年时。
  
  <RewriterConfig>
   <Rules>
   <!-- Rules for Blog Content Displayer -->
   <RewriterRule>
   <LookFor>~/(d{4})/(d{2})/(d{2}).aspx</LookFor>
   <SendTo>~/ShowBlogContent.aspx?year=$1&month=$2&day=$3</SendTo>
   </RewriterRule>
   <RewriterRule>
   <LookFor>~/(d{4})/(d{2})/Default.aspx</LookFor>
   <SendTo><![CDATA[~/ShowBlogContent.aspx?year=$1&month=$2]]></SendTo>
   </RewriterRule>
   <RewriterRule>
   <LookFor>~/(d{4})/Default.aspx</LookFor>
   <SendTo>~/ShowBlogContent.aspx?year=$1</SendTo>
   </RewriterRule>
   </Rules>
  </RewriterConfig>
  
    这些网址重写规则展示了正则表达式的强大威力。第一条规则按照(/d{4})/(/d{2})/(/d{2})/.aspx模式进行查找,通俗的说,它查找是否包含匹配xxxx/xx/xx.aspx格式的字符串,其中x表示数字,每一组数字必须用圆括号括起来,这样可以在相应<SendTo>节内引用圆括号内的匹配字符串。我们可以使用$1、$2、$3来分别引用前面匹配的圆括号组,其中$1,$2,$3分别表示所匹配的第一、第二、第三个圆括号组。
  
    注意:由于web.config是XML格式的文档,所以在文本域内必须回避直接使用一些特殊字符,如:&,<和>符号等。在第一条网址重写规则的<SendTo>节中用&来表示引用&符号,在第二条网址重写规则的<SendTo>节中用<![CDATA[...]]>元素来表示其中所有的内容都是文本域,不再需要用转义字符来表示引用。这两种方法都可以实现同样的目的。
  
    下面图五、图六、图七都显示出网址重写的运行状况。这些数据都真实地摘自作者的Blog,图五显示2003年11月7日的帖子,图六显示所有2003年11月的帖子,图七显示2003年所有帖子。
  
  图五.显示2003年11月7日的帖子
  
  图六. 显示2003年11月所有的帖子
  

 

查看原文
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值