来自 澳门新葡亰 2019-11-27 16:48 的文章
当前位置: 澳门新葡亰app > 澳门新葡亰 > 正文

以此UrlRoutingModule集成到MVC程序聚集了卡塔 尔(阿

率先大家驾驭一下貌似的点子

    我们只供给在web.config配置文件中做映射管理就可以。

 1、概要

当我们新建三个MVC项目时,张开他的Web.Config文件能够发掘

    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 我们知道ScriptModule 类就是管理用于 ASP.NET 中 AJAX 功能的 HTTP 模块,在此我们不做介绍
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> //这个UrlRoutingModule类才是重点
    </httpModules>

本条HttpModule,拦截全部央求,对伏乞举行管理,最后创建和奉行合适的拍卖央浼的HttpHandler(MVC3之后,这么些UrlRoutingModule集成到MVC程序集中了卡塔 尔(阿拉伯语:قطر‎。

 

  当客商端在本地浏览器上输入网站来呼吁大家的一个MVC程序时,服务端接纳到诉求.....此处省略N个字(和asp.net管理相符卡塔尔.....

  HttpApplication的平地风波注册,将在 UrlRoutingModule 注册到HttpApplication的事件中

public class UrlRoutingModule : IHttpModule
{
    protected virtual void Init(HttpApplication application)
    {   //开始只是把要执行的具体方法注册到事件中,等待事件被触发时,在执行已被注册的方法。
        application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache); 
        application.PostMapRequestHandler += new EventHandler(this.OnApplicationPostMapRequestHandler);
    }
}

  注册完事件之后,那么快要开头试行HttpApplication事件。

1、执行Global.asax文件中Application_Start方法。
即:在此将三个和睦定义的路由法则注册到路由集合中。那么些路由集合能够由RouteTable.Routes获得。

 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
        }

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Default", // 路由名称
                "{controller}/{action}/{id}", // 带有参数的 URL
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
            ); //在路由表里添加一条路由规则
        }

第风度翩翩种情势:

 <system.web>
    <urlMappings enabled="true">

      <add url="~/d" mappedUrl="SmackBio.WebSocketSDK.GenericHandler"/>

    </urlMappings>

表明:这里的url便是大家须要在号召的切切实实写法,然后mappedUrl则是我们实际上项目中的管理地点。

其次种情势:

 <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>    
      <add path="/socket" verb="*" name="GenericHandler" type="SmackBio.WebSocketSDK.GenericHandler"/>
    </handlers>
  </system.webServer>

讲明:这里的path正是大家恳请的进口地址,type则是大家的实际项目中的方法类岗位。

2、依次实行HttpApplication的平地风波。  

BeginRequest
AuthenticateRequest
PostAuthenticateRequest
AuthorizeRequest
PostAuthorizeRequest
ResolveRequestCache
PostResolveRequestCache 在UrlRoutingModule类中,在此事件中注册了一个执行方法,即:OnApplicationPostResolveRequestCache
PostMapRequestHandler                                                       OnApplicationPostMapRequestHandler
AcquireRequestState
PostAcquireRequestState
PreRequesHandlerExecute
PostRequeshandlerExecute
ReleaseRequesState
PostReleaseRequestState
UpdateRequestCache
PostUpdateRequestCach
LogRequest
PostLogRequest
EndRequest

OnApplicationPostResolveRequestCache方法

private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{
    HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
    this.PostResolveRequestCache(context);
}
//这里用HttpContextWrapper类包装当前的HttpContext,实质上也是一个请求的上下文。他可以使用诸如Typemock Isolator或Rhino Mocks的Mock对象框进行模拟变得更简单。
//并把这个包装之后的上下文作为PostResolveRequestCache的参数

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

public virtual void PostResolveRequestCache(HttpContextBase context)
{
    RouteData routeData = this.RouteCollection.GetRouteData(context);
//GetRouteData方法内部遍历路由集合中的每个路由对象去和上下文中指定的请求URL去匹配。如成功,就返回当前的路由对象RouteData,如不成功,返回null
//this.RouteCollection就是RouteTable.Routes,即:路由集合。

    if (routeData != null)----这里便是判断是否匹配成功
    {
        IRouteHandler routeHandler = routeData.RouteHandler;----//获取一个处理当前匹配成功的路由的对象
     //这个routeHandler其实就是一个MvcRouteHandle类
     ----因为在第一句中执行的GetRouteData方法中,为RouteData的RouteHandler属性赋值为MvcRouteHandler
        if (routeHandler == null)
        {
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
        }
        if (!(routeHandler is StopRoutingHandler))
        {
            RequestContext requestContext = new RequestContext(context, routeData);//把当前的请求的信息和与当前请求匹配成功的路由信息再包装起来。
            IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
            //根据包装后的请求信息,最终得到一个MvcHandler
       ---MvcRouteHandler中只有一个方法,GetHttpHandler方法,返回MvcHandler,Mvc中处理请求的类。
       ---PageRouteHandler中也只有一个方法,GetHttpHandler方法,返回的是Page,asp.net中处理请求的类。 

澳门新葡亰官网APP 1澳门新葡亰官网APP 2MvcRouteHandler

    public class MvcRouteHandler : IRouteHandler
    {

        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new MvcHandler(requestContext);
        }

        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
        {
            return this.GetHttpHandler(requestContext);
        }
    }

 

          if (httpHandler == null)

            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler.GetType() }));
            }
            //RequestData类是UrlRoutingModule类中嵌套的一个私有类,把处理请求的类和当前请求的虚拟路径
            RequestData data2 = new RequestData {
                OriginalPath = context.Request.Path,
                HttpHandler = httpHandler
            };
            context.Items[_requestDataKey] = data2;
            //把封装的处理类MvcHandler和请求的虚拟路径,赋值到 HttpContextWrapper类中。(这样在用到处理类时,就需要实例化,直接取值即可)
            //HttpContextWrapper类包装当前的HttpContext,实质上也是一个请求的上下文。
            context.RewritePath("~/UrlRouting.axd");

context.RemapHandler(httpHandler);//博客是里这里是这么一句,但是我反编译没找到,可能是版本的问题吧!
//将MvcHandler 实例 映射到管线中(通常我们是利用web.config 进行配置的,但是MvcHandler 没有默认无参构造函数,所以直接通过向其传递一个实例进行映射)

} } } 

OnApplicationPostMapRequestHandler方法
该方法做的事情很简单,就是重写下请求路径,让输出的路径和输入的路径相同,在这里用来记忆输入路径的是context.Items[],从上下两段代码中可以看到.
这个事件负责根据文件扩展名映射到具体的httphandle处理类,而MVC的URL信息没有具体的文件后缀名 为了使处理模块能够在iis7中实现路由,则采取了这么一种简单的解决办法。先把路径指向~/UrlRouting.axd,在此事件中会设置一个UrlRouting.axd类型的Handler避免报错,并在下一步事件中替换掉此处的Handler再把~/UrlRouting.axd这个路径给改回来。

澳门新葡亰官网APP 3澳门新葡亰官网APP 4View Code

private void OnApplicationPostMapRequestHandler(object sender, EventArgs e)
{
    HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
    this.PostMapRequestHandler(context);
}



 public virtual void PostMapRequestHandler(HttpContextBase context)
{
    RequestData data = (RequestData) context.Items[_requestDataKey];
    if (data != null)
    {
        context.RewritePath(data.OriginalPath);
        context.Handler = data.HttpHandler;
    }
}

 

上文中得到了一个MvcHandler类实例,MvcHandler世袭达成了IHttpAsyncHandler, IHttpHandler, IRequiresSessionState五个接口。而那四个接口倘诺都完毕了,在MVC框架下是或不是别的http央求就能够通吃了呢?从MSDN大家获知,事实不是如此的:留意,就算MvcHandler 完成 IHttpHandler,也不可能将其映射为管理程序(比方.mvc 文件扩充名卡塔 尔(英语:State of Qatar),因为此类不扶持无参数构造函数。 (它唯大器晚成的构造函数供给四个RequestContext 对象卡塔尔国 唯独,万幸,大家还应该有MvcHttpHandler。

如你所知,MvcHttpHandler可以“弥补”MvcHandler的不足,为何这么说吗?因为MvcHandler未有无参的构造函数,因而固然MvcHandler实现了 IHttpHandler接口,在IIS中也不可能将其映射为某类文件扩张名的处理程序,而MvcHttpHandler就提供了不通过路由模块的状况下直接管理映射的管理程序。

  • MvcHttpHandler.使用此管理程序可低价达成直接管理程序映射(不经过路由模块卡塔 尔(阿拉伯语:قطر‎。要是要将文件扩大名(如 .mvc卡塔尔国直接照射到叁个 MVC 处理程序,此管理程序将不胜实用。在其间,MvcHttpHandler 将实践 ASP.NET 路由常常性实行(通过 澳门新葡亰app,MvcRouteHandler 和 MvcHandler卡塔尔国的天职。然而,它是用作处理程序并非当作模块来试行这一个任务的。对具备伏乞启用 澳门新葡亰官网APP,UrlRoutingModule 时,日常不使用此管理程序。
  • MvcHandler.此管理程序负担运营MVC 应用程序的 ASP.NET 管道。它从 MVC 调整器工厂选拔 Controller 实例;此调整器管理央求的进一层处理。请注意,即使 MvcHandler 实现了 IHttpHandler,它也无法映照为管理程序(举个例子,针对 .mvc 文件扩充名卡塔尔国,因为此类不扶持无参数构造函数(而管理程序必要是无参数构造函数卡塔 尔(英语:State of Qatar)。(其唯风度翩翩的构造函数必要 RequestContext 对象。)

mvc路由布置情势

那是大家区别应用的照耀格局。可是在mvc路由中我们挂起日常处理程序却发掘不行了,上面大家就要安顿路由艺术实行映射。

在mvc中大家分为三步:

    1.贯彻拍卖代码程序(实现通常管理程序世袭类IHttpHandler卡塔尔

澳门新葡亰官网APP 5澳门新葡亰官网APP 6

 1   public class GenericHandler : IHttpHandler
 2     {
 3         public void ProcessRequest(HttpContext context)
 4         {
 5             if (context.IsWebSocketRequest || context.IsWebSocketRequestUpgrading)
 6             {
 7                 context.AcceptWebSocketRequest(new SBWebSocketHandler());
 8             }
 9             else
10             {
11                 context.Response.ContentType = "text/plain";
12                 context.Response.Write("Service running");
13             }
14         }
15 
16         public bool IsReusable
17         {
18             get
19             {
20                 return false;
21             }
22         }
23     }

View Code

    2.定义两个类路由法则(完成路由IRouteHandler接口然后针对管理代码程序类卡塔 尔(英语:State of Qatar)

澳门新葡亰官网APP 7澳门新葡亰官网APP 8

 public class PlainRouteHandler : IRouteHandler
    {

        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new GenericHandler();
        }
    }

 public static void RegisterHandler(RouteCollection routes)
        {

            RouteTable.Routes.Add("socket",
                 new Route("socket", new MvcZodiac.Controllers.PlainRouteHandler()));
        }

View Code

 

    3.挂号到程序中(在Global.asax中的Application_Start方法注册卡塔尔

 RegisterHandler(RouteTable.Routes);

 这里补充一下,那句话断定要写在路由登记在此之前,不然不会起效果。比如:

澳门新葡亰官网APP 9

 

 3、HttpApplication事件继续施行

BeginRequest
AuthenticateRequest
PostAuthenticateRequest
AuthorizeRequest
PostAuthorizeRequest
ResolveRequestCache
PostResolveRequestCache 
PostMapRequestHandler                                                       
AcquireRequestState
PostAcquireRequestState
PreRequesHandlerExecute
PostRequeshandlerExecute
ReleaseRequesState
PostReleaseRequestState
UpdateRequestCache
PostUpdateRequestCach
LogRequest
PostLogRequest
EndRequest

在11-11个事件的时候得到第7个事件的时候创制的MVCHandler对象试行他的ProcessRequest方法。

public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
{
    protected virtual void ProcessRequest(HttpContext httpContext)
    {
        //使用HttpContextWrapper对HttpContext进行封装,封装的目的是为了解耦以获得可测试性.然后从RequestContext.RouteData中提取Controller名称.
        HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
        this.ProcessRequest(httpContext2);
    }

    protected internal virtual void ProcessRequest(HttpContextBase httpContext)
    {
        IController controller;
        IControllerFactory controllerFactory;
        this.ProcessRequestInit(httpContext, out controller, out controllerFactory); //获取到Controler实例       ----下节详细介绍
        try
        {
                controller.Execute(this.RequestContext); //当前Controler对象的Action的创建与执行                   ----下节详细介绍   
                执行包括:加载TempData, 创建及执行Action,处理Action返回的ActionResult ,保存TempData数据。
        }
        finally
        {
            controllerFactory.ReleaseController(controller); //释放当前Controler对象
        }
    }
}

流程如下图,MvcHandler实例来管理需要,他做为管理的核心,当成功现在,释放当前的Controler实例,继续实行HttpApplication事件

澳门新葡亰官网APP 10

 此图摘自:

本文由澳门新葡亰app发布于澳门新葡亰,转载请注明出处:以此UrlRoutingModule集成到MVC程序聚集了卡塔 尔(阿

关键词: