用微软组件URLRewriter在Windows Server 2003下实现的在ASP.NET下重写URL

14 篇文章 0 订阅

好有成就感的一个晚上啊,虽然困了,也要把晚上的收货整理出来,必须的!
以前粗略的看过一些关于URL重写的文章,大致分为在IIS下、ASP.NET下实现的。还有说在IIS6下不容易实现用ASP.NET重写URL,在IIS7下很容易用ASP.NET实现的。今天通过试验,终于弄清楚其中的奥秘了。
首先在IIS6下不容易截获请求而在IIS7下容易截获请求的说法是错误的,在IIS6下只需要在IIS6的网站属性->主目录->应用程序配置->设置中插入一个“通配符应用程序映射”(C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/aspnet_isapi.dll)。插入这个的作用实际就是:不管是什么类型的文件,比如.html、.asp、.jpg等等,甚至是以/结尾的目录,都发到aspnet_isapi.dll,要由aspnet_isapi.dll来“过目”,如果不做这个配置,那么像.asp可能旧有asp_iisapi.dll来处理了。


这里要确保“确定文件是否存在”处于未选中状态,这样IIS才不会实际去检查文件是否存在,因为重写的URL指向的文件物理上是不存在的。

做了上述配置之后,不管是什么样的URL,都会进入到ASP.NET的处理程序,可以随意重写。

另一个需要注意的问题是,网上有几个不同版本的URL重写方法,给的类也是不同的,配置 web.config的方法也是不同的,所以,千万要弄清,web.config 中的配置很多,不要张冠李戴。

web.config 中需要配置的几个地方列出如下:

  1.    <configSections>
  2.         <section name= "RewriterConfig"  type= "URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
  3.     </configSections>
  4.     <appSettings />
  5.     <connectionStrings>
  1.         <httpModules>
  2.             <add type= "URLRewriter.ModuleRewriter, URLRewriter"  name= "ModuleRewriter" />
  3.         </httpModules>
  4. <!-- 这里网上的资料都是说:可以配置为http处理模块,也可以配置为处理程序,好像两个只要用一个就可以了,我这里用的是处理模块 -->
  1.     <RewriterConfig>
  2.         <Rules>
  3.             <RewriterRule>
  4.                 <LookFor>(.+)/(.+).html</LookFor>
  5.                 <SendTo>~/$2.aspx</SendTo>
  6.             </RewriterRule>
  7.             <RewriterRule>
  8.                 <LookFor>~/(/d{4})/(/d{2})/(/d{2})/.aspx</LookFor>
  9.                 <SendTo>~/ShowBlogContent.aspx?year=$1&month=$2&day=$3</SendTo>
  10.             </RewriterRule>
  11.         </Rules>
  12.     </RewriterConfig>

最后这部份就是控制重写的,只需要用正则表达式匹配请求url,然后给出新的url就可以,这里可以使用正则表达式中的后向引用。

还有一个问题,就是处理回发。
比如访问一个被重写了的url,而这个url上面有一个窗体,虽然打开窗体的时候,使用的是重写前的url,但是当点击窗体的提交按钮的时候,窗体会被定向到重写后的实际的url去。解决这个问题的办法网上也提供了,而且还有vb版本,和C#版本的。
具体的实现方法就是“利用ASP.NET 2.0控件适配器 扩展架构来定制控件的输出”,说白了就是ASP.NET 2.0提供了一个功能,可以手工的改写服务器控件。那么我们可以改写form控件的窗体的action,也就是提交路径的属性,下面给出C#版本,VB版本可以网上搜到。
需要两个文件,分别是:
App_Browsers/Form.browser

  1. <browsers>
  2.     <browser refID= "Default" >
  3.         <controlAdapters>
  4.             <adapter controlType= "System.Web.UI.HtmlControls.HtmlForm"
  5.                      adapterType= "FormRewriterControlAdapter"  />
  6.         </controlAdapters>
  7.     </browser>
  8. </browsers>

App_Code/FormRewriter.cs

  1. using  System.Data;
  2. using  System.Configuration;
  3. using  System.Web;
  4. using  System.Web.Security;
  5. using  System.Web.UI;
  6. using  System.Web.UI.WebControls;
  7. using  System.Web.UI.WebControls.WebParts;
  8. using  System.Web.UI.HtmlControls;
  9. /// <summary>
  10. /// FormRewriter 的摘要说明
  11. /// </summary>
  12. public   class  FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
  13. {
  14.      public  FormRewriterControlAdapter()
  15.     {
  16.     }
  17.      protected   override   void  Render(HtmlTextWriter writer)
  18.     {
  19.          base .Render( new  RewriteFormHtmlTextWriter(writer));
  20.     }
  21. }
  22. public   class  RewriteFormHtmlTextWriter : HtmlTextWriter
  23. {
  24.      public  RewriteFormHtmlTextWriter(HtmlTextWriter writer)
  25.         :  base (writer)
  26.     {
  27.          base .InnerWriter = writer.InnerWriter;
  28.     }
  29.      public  RewriteFormHtmlTextWriter(System.IO.TextWriter writer)
  30.         :  base (writer)
  31.     {
  32.          base .InnerWriter = writer;
  33.     }
  34.      public   override   void  WriteAttribute( string  name,  string  value,  bool  fEncode)
  35.     {
  36.          //If the attribute we are writing is the "action" attribute, and we are not on a sub-control,   
  37.          //then replace the value to write with the raw URL of the request - which ensures that we'll  
  38.          //preserve the PathInfo value on postback scenarios 
  39.          if  (name ==  "action" )
  40.         {
  41.             HttpContext context = HttpContext.Current;
  42.              if  (context.Items[ "ActionAlreadyWritten" ] ==  null )
  43.             {
  44.                  //We will use the Request.RawUrl property within ASP.NET to retrieve the origional   
  45.                  //URL before it was re-written. 
  46.                 value = context.Request.RawUrl;
  47.                  //Indicate that we've already rewritten the &ltform>'s action attribute to prevent  
  48.                  //us from rewriting a sub-control under the &ltform> control  
  49.                 context.Items[ "ActionAlreadyWritten" ] =  true ;
  50.             }
  51.         }
  52.          base .WriteAttribute(name, value, fEncode);
  53.     }
  54. }

经过这么一番折腾后,URL重写就可以在 Windows Server 2003 + IIS6 + ASP.NET 2.0 下实现了。
不过,事情没那么简单,改写是实现了,那么页面上那么多连接的地址都要手工去修改吗?手工修改后在vs.net 的 ide 里面会不会出问题?
留作以后解答……

微软的URL重写类在这里下载,下载后只需编译里面的URLRewriter类为DLL文件,然后在你的项目中做个引用就可以了。
http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值