在 ASP.NET 中执行 URL 重写

在 ASP.NET 中执行 URL 重写

最近在看在 ASP.NET 中执行 URL 重写觉的入门很简单  

1. 下载ms的URLRewriter.dll,放到你的web程序的bin下
http://download.microsoft.com/download/0/4/6/0463611e-a3f9-490d-a08c-877a83b797cf/MSDNURLRewriting.msi)这里是  URLRewriter.dll 的源代码,安装后打开工程自己编译成dll 就行了。

2.配置Web.config

首先,您需要在 Web.config 文件中指明要使用 HTTP 模块还是 HTTP 处理程序来执行 URL 重写。在下载代码中,Web.config 文件包含两个已注释掉的条目:
 
CODE:
<system.web>
<!--
<httpModules>
  <add type="URLRewriter.ModuleRewriter, URLRewriter"
        name="ModuleRewriter" />
</httpModules>
-->

<!--
<httpHandlers>
  <add verb="*" path="*.aspx"
        type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
</httpHandlers>
-->
</system.web>


注释掉 <httpModules> 条目,以使用 HTTP 模块执行重写;注释掉 <httpHandlers> 条目,以使用 HTTP 处理程序执行重写。
除了指定使用 HTTP 模块还是 HTTP 处理程序执行重写外,Web.config 文件还包含重写规则:重写规则由两个字符串组成:要在被请求的 URL 中查找的模式;要替换此模式的字符串(如果找到)。在 Web.config 文件中,此信息是使用以下语法表达的:
 
CODE:
<RewriterConfig>
  <Rules>
  <RewriterRule>
      <LookFor>要查找的模式</LookFor>
      <SendTo>要用来替换模式的字符串</SendTo>
  </RewriterRule>
  <RewriterRule>
      <LookFor>要查找的模式</LookFor>
      <SendTo>要用来替换模式的字符串</SendTo>
  </RewriterRule>
  ...
  </Rules>
</RewriterConfig>


每个重写规则均由 <RewriterRule> 元素表达。要搜索的模式由 <LookFor> 元素指定,而要替换所找到的模式的字符串将在 <SentTo> 元素中输入。这些重写规则将从头到尾进行计算。如果发现与某个规则匹配,URL 将被重写,并且对重写规则的搜索将会终止。
在 <LookFor> 元素中指定模式时,请注意,要使用正则表达式来执行匹配和字符串替换。(稍后,我们将介绍一个真实的示例,说明如何使用正则表达式来搜索模式。)由于模式是正则表达式,应确保转义正则表达式中的任何保留字符。(一些正则表达式保留字符包括:.、?、^、$ 及其他。可以通过在前面加反斜杠(如 \.)对这些字符进行转义,以匹配文字句点。)

3.使用 URL 重写引擎执行简单的 URL 重写
 
CODE:
<!--这里要加入一个RewriterConfig用来配置规则-->
  <RewriterConfig>
    <Rules>
      <RewriterRule>
        <!--匹配guid参数-->
        <LookFor>~/([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})\/Class.aspx</LookFor>
        <SendTo><![CDATA[~/Class/Default.aspx?id=$1]]></SendTo>
        <!--即访问类似于~/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx的页面将发往~/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b-->
      </RewriterRule>
      <RewriterRule>
        <!--匹配guid参数-->
        <LookFor>~/(\d{1,10})/([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})\/Class.aspx</LookFor>
        <SendTo>
          <![CDATA[~Class/Default.aspx?page=$1&id=$2]]></SendTo>
        <!--即访问类似于~/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx的页面将发往~/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b-->
      </RewriterRule>
      <!--
      注意:由于 Web.config 文件采用 XML 格式,但是必须对元素文字部分中的字符(如 &、< 和 >)进行转义。
      在第一个规则的 <SendTo> 元素中,& 被转义为 &amp;。
      在第二个规则的 <SendTo> 中使用了另外一种技术(使用 <![CDATA[...]]> 元素),无需对内部的内容进行转义。
      可以使用两种方法中的任何一种,并且都会得到相同的结果。
      -->
    </Rules>
  </RewriterConfig>



注意:
1。  ([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})
        匹配正则表达式(任意8个字母或数字)- (任意4个字母或数字)-(任意4个字母或数字)-(任意12个字母或数字)
            如: 9e808623-f0f9-49c4-86f2-9891015d405b
2。 <![CDATA[~/Class/Default.aspx?id=$1]]>  这个$1 用到是正则表达式中 反向引用的概念,不懂的就查  一下了。

如:字符串 "#123456"  正则表达式:/#(\d+)/  在括号中就是一个方向引用($1),($1)的值就是123456       

懂了上面的以后就简单了:
当在地址栏输入: http://localhost:3721/URLRewriter/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx
他就会自动转向:http://localhost:3721/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b

 

 

------------------------------------------------------------------------------------------------------------

完整的config 配置

CODE:
<?xml version="1.0"?>
<configuration>
  <!--这里要加入一个configSections节-->
  <configSections>
    <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
  </configSections>
  <!--这里要加入一个RewriterConfig用来配置规则-->
  <RewriterConfig>
    <Rules>
      <RewriterRule>
        <!--匹配guid参数-->
        <LookFor>~/([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})\/Class.aspx</LookFor>
        <SendTo><![CDATA[~/Class/Default.aspx?id=$1]]></SendTo>
        <!--即访问类似于~/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx的页面将发往~/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b-->
      </RewriterRule>
      <RewriterRule>
        <!--匹配guid参数-->
        <LookFor>~/(\d{1,10})/([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})\/Class.aspx</LookFor>
        <SendTo>
          <![CDATA[~Class/Default.aspx?page=$1&id=$2]]></SendTo>
        <!--即访问类似于~/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx的页面将发往~/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b-->
      </RewriterRule>
      <RewriterRule>
        <!--匹配guid参数-->
        <LookFor>~/([A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12})\.aspx</LookFor>
        <SendTo><![CDATA[~/Class/Default.aspx?id=$1]]></SendTo>
        <!--即访问类似于~/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx的页面将发往~/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b-->
      </RewriterRule>
      <!--
      注意:由于 Web.config 文件采用 XML 格式,但是必须对元素文字部分中的字符(如 &、< 和 >)进行转义。
      在第一个规则的 <SendTo> 元素中,& 被转义为 &amp;。
      在第二个规则的 <SendTo> 中使用了另外一种技术(使用 <![CDATA[...]]> 元素),无需对内部的内容进行转义。
      可以使用两种方法中的任何一种,并且都会得到相同的结果。
      -->
    </Rules>
  </RewriterConfig>
  <appSettings/>
<connectionStrings/>
 
<system.web>
   
    <httpHandlers>
      <!--这里加入urlRewriter.dll要处理的后缀文件-->
      <add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />     
    </httpHandlers>
    <compilation debug="true"/> 
  <authentication mode="Windows"/> 
</system.web>
</configuration>

-----------------------------------------------------------------------------------------------------------


如果要重写的 URL 中包含一个服务器端的 Web 窗体并执行回发,则窗体回发后,将使用真实的 URL。也就是说,如果用户在浏览器中输入 URLRewriter/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx,他们在浏览器地址栏中看到的将是 URLRewriter/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx,但是他们看到的内容将是 Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b 的内容。如果此时本页面执行了回发,用户将被回发到Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b ,而不是URLRewriter/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx这样不会中断任何内容,但是单击按钮时突然看到真正的URL 。

也就是说本来地址栏显示的是重定向后的:http://localhost:3721/URLRewriter/9e808623-f0f9-49c4-86f2-9891015d405b/Class.aspx  但是当点击一个服务器控件比如(button)触发回掉事件后 地址栏显示的是 没重定向前的URL 地址了http://localhost:3721/Class/Default.aspx?id=9e808623-f0f9-49c4-86f2-9891015d405b

解决办法:
由于继承功能,我们可以获得 HtmlForm 类的所有功能,并且只需添加几行代码即可获得所需的行为。以下显示了自定义类的完整代码:

CODE:
namespace ActionlessForm {
  public class Form : System.Web.UI.HtmlControls.HtmlForm
  {
    protected override void RenderAttributes(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", base.ClientID);
    }
  }
}



已被覆盖的 RenderAttributes() 方法的代码仅包含 HtmlForm 类的 RenderAttributes() 方法的准确代码,而不设置操作属性。(我使用 Lutz Roeder 的 Reflector 来查看 HtmlForm 类的源代码。)
创建此类并对其进行编译之后,要在 ASP.NET Web 应用程序中使用它,应首先将其添加到 Web 应用程序的 References 文件夹中。然后,要使用它来代替 HtmlForm 类,只需在 ASP.NET 网页的顶部添加以下内容即可:

CODE:
<%@ Register TagPrefix="skm" Namespace="ActionlessForm" Assembly="ActionlessForm" %>
然后,将 <form runat="server">(如果有)替换为:<skm:Form id="Form1" method="post" runat="server">
并将右边的 </form> 标记替换为: </skm:Form>



注意:如果要重写的目标 URL 没有执行回发,则无需使用此自定义 Web Form 类。

posted @ 2008-07-29 11:13  supers  阅读(196)  评论(0)    收藏  举报