zoukankan      html  css  js  c++  java
  • asp.net与MVC4的路由原理和过程【学习笔记】

    当IIS收到一个http请求,把请求信息发给对应的HttpModel(实际是实现类UrlRoutingModule),在HttpModel中会注册HttpApplication 类中的PostResolveRequestCache事件,通过此事件来动态选择映射HttpHandler处理程序。通过匹配到的RouteData类的RouteHandler属性得到IRouteHandler对象(MVC4MvcRouteHandlerasp.net原生的是PageRouteHandler),通过这个对象的GetHttpHandler方法就可以得到HttpHandler处理程序。具体代码如下:

    public virtual void PostResolveRequestCache(object sender, EventArgs e) {
    
       HttpApplication app = (HttpApplication)sender;
    
           HttpContextBase context = new HttpContextWrapper(app.Context);
           //详细见附1
           RouteData routeData = RouteCollection.GetRouteData(context);
           if (routeData == null) {
                return;
           }
           //详细见附1
           IRouteHandler routeHandler = routeData.RouteHandler;
           if (routeHandler is StopRoutingHandler) {
               return;
           }
           RequestContext requestContext = new RequestContext(context, routeData);
           context.Request.RequestContext = requestContext;
           IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); 
           if (httpHandler is UrlAuthFailureHandler) {
               if (FormsAuthenticationModule.FormsAuthRequired) {
                     UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
                return;
              }
              else {
               throw new HttpException(401, SR.GetString(SR.Assess_Denied_Description3));
              }
          }
          context.RemapHandler(httpHandler);//动态指定HttpHandler
     }
    

     

    1

    RouteCollection.GetHttpHandler方法获取匹配当前路由信息的RouteData,此方法是循环遍历RouteCollection集合并调用集合中RouteBase实现类为Route)的GetRouteData方法,并返回第一个不为NullRoudataRoudata实在RoudataBaseGetRouteData方法中被创建的,详见如下代码:

     public override RouteData GetRouteData(HttpContextBase httpContext) {
         string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
         RouteValueDictionary values = _parsedRoute.Match(requestPath, Defaults);
         if (values == null) {
              return null;
         }
        //为Roudata指定IRouteHandler对象
        RouteData routeData = new RouteData(this, RouteHandler);     
    if (!ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest)) {
              return null;
         }
         foreach (var value in values) {
              routeData.Values.Add(value.Key, value.Value);
         }
         if (DataTokens != null) {
              foreach (var prop in DataTokens) {
                 routeData.DataTokens[prop.Key] = prop.Value;
              }
         }
        return routeData;
     }
     
    public class RouteData {
            private IRouteHandler _routeHandler; 
            public RouteData() {
            }
            public RouteData(RouteBase route, IRouteHandler routeHandler) {
                Route = route;
                RouteHandler = routeHandler;
            }
    //更多代码
    }
    

    MVC4:动态指定到HttpHandler后,就是处理Controller的创建和Action的执行了

    HttpHandler根据Routedata获取到Controller的名称,然后通过ControllerBuilder的静态方法GetControllerFactory获取IControllerFactory的实现类(默认是DefaultControllerFactory )来创建请求的IController的实现类的实例。最后执行IControllerExecute方法并传入请求上下文,方法Execute实现在System.Web.Mvc.ControllerBase这个抽象类中,Execute最终调用的是System.Web.Mvc.Controller中的ExecuteCore方法,ExecuteCore方法主要是保存TempData然后根据路由数据调用执行Action。代码如下:

     

    protected override void ExecuteCore()
    {
       PossiblyLoadTempData();
       try
       {
          string actionName = GetActionName(RouteData);
    //ActionInvoker是System.Web.Mvc.Controller的属性,该属性是一个返回类型为IActionInvoker的action执行器 if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) { HandleUnknownAction(actionName); } } finally { PossiblySaveTempData(); } }
  • 相关阅读:
    SetThreadAffinityMask设置线程亲缘性
    Delphi 获取北京时间(通过百度和timedate网站)
    delphi 实现微信开发
    翻书的效果:FMX.TSwipeTransitionEffect Animation
    [每日一题] OCP1z0-047 :2013-07-15 drop column
    Delphi获取当前系统时间(使用API函数GetSystemTime)
    Delphi代码中嵌入ASM代码
    Delphi Jpg和Gif转Bmp
    Delphi RichEdit的内容保存为图片
    Delphi 实现任务栏多窗口图标显示
  • 原文地址:https://www.cnblogs.com/lxiang/p/3953744.html
Copyright © 2011-2022 走看看