zoukankan      html  css  js  c++  java
  • ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12)

    转自http://www.cnblogs.com/darrenji/p/3795676.html

    在上一篇"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)

  • 相关阅读:
    进程与线程
    二维数组和指向指针的指针
    _variant_t 到 CString 转换
    1.15 构造数独
    单链表的一些操作
    C++关键字(2)——extern
    the seventh chapter
    Visual C++ 数据库开发的特点
    CString 和 LPCTSTR区别【转】
    2.5 寻找最大的K个数
  • 原文地址:https://www.cnblogs.com/cxzdy/p/3809232.html
Copyright © 2011-2022 走看看