要介绍这两个内容,必须要从ASP.NET管线说起。

管线(Pipeline)这个词形象地说明了每个Asp.net请求的处理过程: 请求是在一个管道中,要经过一系列的过程点,这些过程点连接起来也就形成一条线。 这些一系列的过程点,其实就是由HttpApplication引发的一系列事件,通常可以由HttpModule来订阅, 也可以在Global.asax中订阅,这一系列的事件也就构成了一次请求的生命周期。

下面通过两张图片来详细说明一下请求的过程

第一张图,主要展示:请求的过程

URL重写与URL路由

从上面的图中,我们可以看出

1.请求先交给HttpModule处理,然后由HttpModule交给HttpHandler,最后再由HttpHandler交回给HttpModule,由HttpModule结束请求。

2.Session的有效期,只有在HttpHandler处理时有效。HttpModule处理时,都是无效的。

3.整个过程由一系列的事件组成,这点正应验了前面对管线的定义。

第二张图,主要说明:管线中所有事件的意义

URL重写与URL路由

 

注意:这是iis7的处理过程,其中多了LogRequest与PostLogRequest这两个事件。iis6的处理过程并没有这两个事件。

对于各个事件的含义,我想图片已经解释的很清楚了。

 

下面通过一个案例,来讲解一下本篇博客的主题。

案例需求:第三方以这样的url:http://host:port/xxxx/mobile/form?Id=xxxxx。向系统发出请求时。系统可以将该url映射到对应的业务层。由于本次主要讲解的重点不在业务层,所以就将该url直接映射到一个简单业务层,输入Hello+Query

URL重写

中心思想:将请求的url重写成服务器可以处理的url形式。然后由服务器根据重写后的url,查找出可以处理重写后的url的Handler,最后由Handler对其进行处理。

思路:

1.定义url重写后的样子。比如将url:http://host:port/xxxx/mobile/form?Id=xxxxx。重写成:http://host:port/xxxx/mobile/service.mobile?Id=xxxxx。

2.编写自定义Module:IHttpModule,检测url是否是需要重写的url,如果是重写url。由管线根据重写后的url来寻找对应的Handler对其进行处理

3.编写自定义Handler:IHttpHandler,来处理重写后的url。

步骤:

1.编写自定义Module

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Service
{
    /// <summary>
    /// url重写Module
    /// </summary>
    internal class UrlRewriteModule : IHttpModule
    {
        /*
         * 为了演示简单,直接写死地址
         * 这里我写了两个url,一个从虚拟路径的根路径重写(我本机的虚拟路径是/Web);另一个从url的末尾处重写
         * 具体用哪个url,根据需求。但是有一点要注意,如果采用根路径重写方式,
         * 那么服务器上的虚拟路径、重写后的url的虚拟路径、Web.config中<httpHandlers>节点下配置的path的虚拟路径都必须相同,
         * 否则Module无法根据url映射对应的Handler
         */
        public static string rootUrlPattern = "/Web/service.mobile";
        //public static string urlPattern = "service.mobile";

        public void Init(HttpApplication app)
        {
            app.PostAuthorizeRequest += app_PostAuthorizeRequest;
        }

        void app_PostAuthorizeRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;

            //检测是否是要重写的url(这里最好用正则表达式匹配)
            if (app.Context.Request.Url.PathAndQuery.Contains("mobile/form"))
            {
                //检查url中是否带有参数
                int p = app.Request.Path.IndexOf("?");
                if (p > 0)
                {
                    //重写url,并且将url参数进行拼接
                    app.Context.RewritePath(rootUrlPattern
                        + "&" + app.Request.Path.Substring(p + 1));
                }
                else
                {
                    //重写url(url中不带参数)
                    app.Context.RewritePath(rootUrlPattern);
                }
            }
            
        }
        
        public void Dispose()
        {
        }
    }
}
View Code

相关文章: