ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12)

在上一篇"ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6) ",体验了1-6关键环节,本篇继续。

 

  ⑦根据IsapiWorkerRequest对象,HttpRuntime创建HttpContext对象


7

 

  ⑧HttpApplicationFactory创建新的或者从HttpApplication池获取现有的、可用的HttpApplication对象

HttpApplication的工作包括:

● 初始化的时候加载全部的HttpModule
● 接收请求
● 在不同阶段引发不同的事件,使得HttpModule通过订阅事件的方式加入到请求的处理过程中
● 在一个特定阶段获取一个IHttpHandler实例,最终将请求交给具体的IHttpHandler来实现

8

 

  ⑨接下来,就是HttpModules发挥作用的时候


9


所有的HttpModules都实现了IHttpModule接口:

public interface IHttpModule

{

  void Init(HttpApplication app);

  void Dispose();

}

可见,HttoModules正是由Init方法,根据传入的HttpApplication类型参数,订阅了HttpApplication的所有事件。

我们自定义一个HttpModule:

public class TestModule : IHttpModule

{

  public void Dispose(){}

  public void Init(HttpApplication app)

  {

    app.PostAcquireRequestState += new EventHandler(app_PostAcuiredRequestState);

    app.PreRequestHandlerExecute += new EventHandler(app_PreRequestHandlerExecute);

  }



  void app_PreRequestHandlerExecute(object sender, EventArgs e)

  {

    //TODO:

  }



  void app_PostAcquiredRequestState(object sender, EventArgs e)

  {

    //TODO:

  }

}

 

  ⑩当某个请求与一个规则匹配后,ASP.NET会调用匹配的HttpHandlerFactory的GetHandler方法来获取一个HttpHandler实例, 最后由一个HttpHandler实例来处理当前请求,生成响应内容


10

所有的HttpHandlers都实现了IHttpHandler接口:

public interface IHttpHandler

{

  bool IsReusable{get;}

  void ProcessRequest(HttpContext context);

}

比如我们可以自定义一个HttpHandler来响应一类特定的请求:

public class Login : IHttpHandler

{

  public void ProcessRequest(HttpContext context)

  {

    context.Response.ContentType = "text/plain";

    string username = context.Request.Form["name"];

    string password = context.Request.Form["password"];



    if(password="sth")

    {

      System.Web.Security.FormsAuthentication.SetAuthCookie(username, false);

      context.Response.Write("ok");

    }

    else

    {

      context.Response.Write("用户名和密码不正确");

    }

  }

}

 

⑾ASP.NET MVC的入口在UrlRoutingModule,即订阅了HttpApplication的第7个管道事件PostResolveRequestCahce,换句话说,是在HtttpApplication的第7个管道事件处对请求进行了拦截


11

 

UrlRouteModlue实现了IHttpModule:

public class UrlRoutingModule : IHttpModule

{

    // Fields

    private static readonly object _contextKey = new object();

    private static readonly object _requestDataKey = new object();

    private RouteCollection _routeCollection;

 

    // Methods

    protected virtual void Dispose()

    {

    }

 

    protected virtual void Init(HttpApplication application)

    {

        if (application.Context.Items[_contextKey] == null)

        {

            application.Context.Items[_contextKey] = _contextKey;

            application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);

        }

    }

 

    private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)

    {

        HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);

        this.PostResolveRequestCache(context);

    }

 

    [Obsolete("This method is obsolete. Override the Init method to use the PostMapRequestHandler event.")]

    public virtual void PostMapRequestHandler(HttpContextBase context)

    {

    }

 

    public virtual void PostResolveRequestCache(HttpContextBase context)

    {

        RouteData routeData = this.RouteCollection.GetRouteData(context);

        if (routeData != null)

        {

            IRouteHandler routeHandler = routeData.RouteHandler;

            if (routeHandler == null)

            {

                throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));

            }

            if (!(routeHandler is StopRoutingHandler))

            {

                RequestContext requestContext = new RequestContext(context, routeData);

                context.Request.RequestContext = requestContext;

                IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);

                if (httpHandler == null)

                {

                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[] { routeHandler.GetType() }));

                }

                if (httpHandler is UrlAuthFailureHandler)

                {

                    if (!FormsAuthenticationModule.FormsAuthRequired)

                    {

                        throw new HttpException(0x191, SR.GetString("Assess_Denied_Description3"));

                    }

                    UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);

                }

                else

                {

                    context.RemapHandler(httpHandler);

                }

            }

        }

    }

 

    void IHttpModule.Dispose()

    {

        this.Dispose();

    }

 

    void IHttpModule.Init(HttpApplication application)

    {

        this.Init(application);

    }

 

    // Properties

    public RouteCollection RouteCollection

    {

        get

        {

            if (this._routeCollection == null)

            {

                this._routeCollection = RouteTable.Routes;

            }

            return this._routeCollection;

        }

        set

        {

            this._routeCollection = value;

        }

    }

}

UrlRoutingModule是在Web.config或默认的web.config中配置:

<httpModules>

            ......

            <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />

        </httpModules>

 

  ⑿而在请求到达UrlRoutingModule之前,我们在全局文件中做了如下配置

public class MvcApplication : System.Web.HttpApplication

    {

        protected void Application_Start()

        {

            ......

            BundleConfig.RegisterBundles(BundleTable.Bundles);

        }

    }



    public class RouteConfig

    {

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");



            routes.MapRoute(

                name: "Default",

                url: "{controller}/{action}/{id}",

                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

            );

        }

    }

这意味着:在HttpApplication的第一个管道事件BeginRequest处,通过MapRoute()方法把路由注册到了RouteCollection中。在实际使用中,UrlRoutingModule是通过RouteTable的静态属性RouteCollection获取路由。

12

 

ASP.NET MVC请求处理管道生命周期的19个关键环节系列包括:

ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6)

ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12)

ASP.NET MVC请求处理管道生命周期的19个关键环节(13-19)

你可能感兴趣的:(asp.net)