天天看点

使用UrlRewriter进行Url重写的完整解决方案[转]

将其添加到web项目的bin目录下

配置:打开web.config,在configsecions中添加sectionhandler:

<section name="rewriter" requirepermission="false" type="intelligencia.urlrewriter.configuration.

rewriterconfigurationsectionhandler, intelligencia.urlrewriter" />

添加这个section是为了它能够处理web.config中的节;然后对urlrewriter配置url重写规则:

<rewriter>

    <rewrite url=”~/lmh$” to=”~/users.aspx?user=lmh” processing=”stop” />

</rewriter>

使rewriter生效:urlrewriter是在httpmodule中做url重写的,要使重写生效,就得先把httpmodule添加到web.config中:

<httpmodules>

    <add name="urlrewriter" type="intelligencia.urlrewriter.rewriterhttpmodule, intelligencia.urlrewriter"/>

</httpmodules>

让rewriter有机会重写url: 当iis收到一个请求时,并不是都会扔给asp.net(aspnet_isapi.dll)来处理,比如静态html,默认情况下,当请求html页面时,iis直接就把结果抛给了客户端,之所以.aspx页面会被asp.net引擎处理,是因为在iis有进行处理程序映射,.aspx被映射到aspnet_isapi.dll,所以当iis收到请求时,先看后缀名,如果是aspx,那就把它交给aspnet_isapi.dll来处理。因为urlrewriter是asp.net级别的重写组件,所以,假如要想执行setp3中例子那样的重写,得先让urlrewriter有机会收到这个地址的请求才行(默认urlrewriter是没机会处理这个url的,因为iis收到这个地址的请求时,因为它没有映射到aspnet_isapi.dll,所以会直接抛出404找不到的错误,因此,要替它做这个映射。打开iis,在属性中有这一项,我们可以让*映射到aspnet_isapi.dll,这样所有的文件都交给asp.net来处理了,urlrewriter也就有机会出手了。

如果用的是iis7.0,则不用这么麻烦,整个setp4可以简化为:在web.config中的节的节中添加上urlrewriter:.webserver>

<add name="urlrewriter" type="intelligencia.urlrewriter.rewriterhttpmodule, intelligencia.urlrewriter"/>

这会保证所有的请求都会经过asp.net的这个module。

现在,重写就算基本完成了,但有几个问题:

 图片可能不显示:如果进行url rewirte并且页面中的图片引用是使用相对路径的话,很可能会发现图片无效了,这是因为,假如/users/lmh会被重写为/users.aspx?user=lmh,而users.aspx上有一张图片,放在相同目录下:logo.gif,(users.aspx中是<img src='logo.gif' />)那当请求/users/lmh时,浏览器对logo.gif的请求的路径将变成/users/logo.gif,而实际上logo.gif是要用/logo.gif才能请求得到的,所以,为了保证url rewrite后不会出现这个问题,需要使用<img src='/logo.gif' />,但是当使用urlrewriter时,对于css,如果代码中是,而实际用users/lmh去请求的话,会发现其实已经变成了,而图片,如果是用的服务器控件的话,也可以继续使用相对路径,就不存在标题中的问题。

使用UrlRewriter进行Url重写的完整解决方案[转]
使用UrlRewriter进行Url重写的完整解决方案[转]

 1

使用UrlRewriter进行Url重写的完整解决方案[转]

    public class formrewritercontroladapter : system.web.ui.adapters.controladapter

 2

使用UrlRewriter进行Url重写的完整解决方案[转]

    {

 3

使用UrlRewriter进行Url重写的完整解决方案[转]

        protected override void render(htmltextwriter writer)

 4

使用UrlRewriter进行Url重写的完整解决方案[转]

        {

 5

使用UrlRewriter进行Url重写的完整解决方案[转]

            base.render(new rewriteformhtmltextwriter(writer));

 6

使用UrlRewriter进行Url重写的完整解决方案[转]

        }

 7

使用UrlRewriter进行Url重写的完整解决方案[转]

    }

 8

使用UrlRewriter进行Url重写的完整解决方案[转]

 9

使用UrlRewriter进行Url重写的完整解决方案[转]

    public class rewriteformhtmltextwriter : htmltextwriter

10

使用UrlRewriter进行Url重写的完整解决方案[转]

11

使用UrlRewriter进行Url重写的完整解决方案[转]

        public rewriteformhtmltextwriter(htmltextwriter writer)

12

使用UrlRewriter进行Url重写的完整解决方案[转]

            : base(writer)

13

使用UrlRewriter进行Url重写的完整解决方案[转]

14

使用UrlRewriter进行Url重写的完整解决方案[转]

            this.innerwriter = writer.innerwriter;

15

使用UrlRewriter进行Url重写的完整解决方案[转]

16

使用UrlRewriter进行Url重写的完整解决方案[转]

17

使用UrlRewriter进行Url重写的完整解决方案[转]

        public override void writeattribute(string name, string value, bool fencode)

18

使用UrlRewriter进行Url重写的完整解决方案[转]

19

使用UrlRewriter进行Url重写的完整解决方案[转]

            if (name == "action")

20

使用UrlRewriter进行Url重写的完整解决方案[转]

            {

21

使用UrlRewriter进行Url重写的完整解决方案[转]

                httpcontext context = httpcontext.current;

22

使用UrlRewriter进行Url重写的完整解决方案[转]

23

使用UrlRewriter进行Url重写的完整解决方案[转]

                value = context.request.rawurl;

24

使用UrlRewriter进行Url重写的完整解决方案[转]

            }

25

使用UrlRewriter进行Url重写的完整解决方案[转]

             base.writeattribute(name, value, fencode);

26

使用UrlRewriter进行Url重写的完整解决方案[转]

27

使用UrlRewriter进行Url重写的完整解决方案[转]
使用UrlRewriter进行Url重写的完整解决方案[转]

这段代码是来自jeffery zhao的博客文章(我去掉了其中一些代码,只保留了保证会工作的最基本代码)。

需要说明的一点是:htmltextwriter有两个writeattribute方法:

public virtual void writeattribute(string name, string value, bool fencode)

public virtual void writeattribute(string name, string value)

重写下面的那个writeattribute是不能成功的,必须重写上面那个方法。为什么呢?先调试看看。

会发现如果重写的是上面那个方法,则会有一次传进来的name值是"action",如我所愿,而重写下面那个方法则没发现传进来值是”action”的name参数。这是怎么搞的?

首先我们要知道,下面那个方法其实是简单的调用了上面的writeattribute :

public virtual void writeattribute(string name, string value) {

      writeattribute(name, value, false /*encode*/);

}

这是framework中的源码。那么,我们所可以猜测到的,就是action这个属性不是通过调用writeattribute(“action”, “…”)来渲染的,而是直接调用wrtiteattribute(“action”, “…”, …),那我们就打开htmlform的源代码看看吧(没有源代码的可以用reflector看),找到htmlform.renderattributes(htmltextwrtier writer)方法,其中有几行:

writer.writeattribute("method", method);

attributes.remove("method");

// encode the action attribute - asurt 66784

writer.writeattribute("action", getactionattribute(), true /*encode*/);

attributes.remove("action");

我们重点看的是上面加粗并下划线的那两行,可以很清楚的看到,当渲染”method”属性时,只是调用了

而渲染action属性则是调用了

那么,答案也就浮出水面了。

接下来,我们要让这个adapter起作用(上面之所以可以调试,是因为我已经让其起作用了,只是还没写出来)。添加asp.net folder:app_browses,新建一个browser文件:

<browsers>

    <browser refid="default">

      <controladapters>

        <adapter controltype="system.web.ui.htmlcontrols.htmlform"

                 adaptertype="formrewritercontroladapter"/>

      </controladapters>

    </browser>

</browsers>

因为上面的formrewritercontroladapter是写在app_code中的,所以不需要添加命名空间。

上面说的是一种防止postback后地址还原的办法,还有一种办法就是利用urlrewriter自带的form控件,这个方法还不需要写这么多代码:

首先,要先注册控件:

<%@ register namespace="intelligencia.urlrewriter" assembly="intelligencia.urlrewriter" tagprefix="rewriter" %>

然后用<rewriter:form runat="server"></form>代替掉原来的<form runat="server"></form>就可以了。

这么一来,使用urlrewriter进行asp.net级别的urlrewrite就弄好了。

欢迎加群互相学习,共同进步。qq群:ios: 58099570 | android: 330987132 | go:217696290 | python:336880185 | 做人要厚道,转载请注明出处!http://www.cnblogs.com/sunshine-anycall/archive/2009/08/05/1539979.html