• 仅此一文让你明白ASP.NET MVC原理


    ASP.NET MVC由以下两个核心组成部分构成:

    1. 一个名为UrlRoutingModule的自定义HttpModule,用来解析Controller与Action名称;
    2. 一个名为MvcHandler的自定义HttpHandler,用来实现对Controller的激活和Action的执行;

    !!阅读本文前请先弄明白asp.net执行的流程及httpmodule与httphandler的作用。

    下面是进行路由转换时相关类的简化结构图:

    http://www.cnblogs.com/DotCpp/

     整个ASP.NET MVC系统的路由信息全部存放在RoteTable这个类的静态变量Routes(为一个RouteDictionary类型)中,网站开始运行时,在Application_Start中对路由进行注册:

    RouteTable.Routes.Add("default", 
          new Route{Url="{controller}/{action}"});

    当一个URL请求到来时,被UrlRoutingModule拦截,拦截后执行流程如下:

    1. 封装当前http上下文,变为HttpContextWrapper对象。
    2. 根据当前的http上下文,从Routes中得到与当前请求URL相符合的RouteData对象。该对象存储有RouteHandler信息。
    3. 把RouteData与http上下文请求封装成一个RequestContext对象。
    4. 根据RequestContext对象,从RouteData的RouteHandler中获取IHttpHandler。
    5. 执行IHttpHandler,进行请求的真正处理。

    执行时序图如下图所示:

    http://www.cnblogs.com/DotCpp/

    UrlRoutingModule的代码如下:

    HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);
    RouteData routeData = RouteTable.Routes.GetRouteData(httpContext);
    RequestContext requestContext = new RequestContext{ data = routeData, context= httpContext};
    IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext);
    httpContext.RemapHandler(handler);

     经过上面最后一步,执行HttpHandle后,程序正式进入Controller激活里面,相关类关系如下图所示:

    http://www.cnblogs.com/DotCpp/

    同URL路由一样,MVC初始化时,也需要注册控制器的一些信息,这里是要让框架知道默认的控制器工厂是什么,所以在Application_Start中:

    ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory());

    程序通过上面的URL路由转换后,进入HttpHandle中,经过以下步骤实现对Controller的激活:

    1. 从Requestcontext封装的RouteData中得到Controller名字。
    2. 通过ControllerBuilder得到当前默认的Controller工厂。
    3. 根据Controller的名字,创建控制器对象(在ControllerFactory初始化的时候,会扫描整个程序集中所有实现IController接口的控制器类型,所以当调用CreateController时,实际上是直接获取)。
    4. 最后执行控制器。执行的实质其实就是执行ActionInvoker.InvokeAction,即根据请求上下文执行相应的Action。

    http://www.cnblogs.com/DotCpp/

    在自定义的MvcHandler中,代码如下:

    string controllerName =this.Requestcontext.RouteData.Controller;
    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
    //通过controllerName得到Control(如HomeController) IController controller
    = controllerFactory.CreateController(this.RequestContext,controllerName); controller.Execute(this.RequestContext);

    一个典型的IActionInvoker接口实现ControllerActionInvoker的InvokeAction方法如下:

    public void InvokeAction(ControllerContext controllerContext,
                   string actionName)
    {
        //找到Action方法
        MethodInfo method = controllerContext.Controller.GetType().GetMethods()
        .First(m=>string.Compare(actionName,m.Name,true)==0);
        
        //获取Action参数,并进行Model绑定
        List<object> parameters = new List<object>();
        foreach(ParameterInfo parameter in method.GetParameters())
            {
                parameters.Add(this.ModelBinder.BindModel(controllerContext,
                    parameter.Name, parameter.ParameterType));
            }
    
        //执行Action,并得到ActionResult
        ActionResult actionResult = method.Invoke(controllerContext.Controller,
            parameters.ToArray()) as ActionResult;
    
        //最终ActionResult用HttpResponse将数据传回客户进行显示
        actionResult.ExecuteResult(controllerContext);
    
    }

    最终形成一个Http Response传回到客户端!!

    以上即为我整理的ASP.NET MVC的两个核心流程,希望新手看的明白,老手多多指点其中的问题,谢谢!!有时间会继续放出MVC其它核心技术。如Model绑定、数据验证等,同时认真向Artech学习!!!!

  • 相关阅读:
    leetcode 86. Partition List
    leetcode 303. Range Sum Query
    leetcode 1310. XOR Queries of a Subarray
    leetcode 1309. Decrypt String from Alphabet to Integer Mapping
    leetcode 215. Kth Largest Element in an Array
    将numpy.ndarray写入excel
    leetcode 1021 Remove Outermost Parentheses
    leetcode 1306. Jump Game III
    leetcode 1305. All Elements in Two Binary Search Trees
    ICCV2019 oral:Wavelet Domain Style Transfer for an Effective Perception-distortion Tradeoff in Single Image Super-Resolution
  • 原文地址:https://www.cnblogs.com/yubaolee/p/3269043.html
Copyright © 2020-2023  润新知