zoukankan      html  css  js  c++  java
  • 谈MVC运行机制,源码剖析

    MVC整体运行机制:

     

    首先我们在浏览器段输入网址:http://www.sina.com/news/society/1,回车。浏览器会通过DNS解析器,解析出域名的对应IP地址,通过IP地址连接到对应的主机的服务器。

    连接服务器后,服务器首先会调用扩展程序ASPNET_ISAPI.dll进行处理,之后会调用这个程序集里的IsAPIRuntime类,创建一个HttpWorkRequest对象,内部存放有请求报文源信息.

     

    HttpWorkerRequest对象内部一览

    接着执行HttpRuntimeProcessRequest方法,将HttpWorkRequest作为参数创建HttpContext对象,HttpContextInit方法会通过对象创建HttpResponse,HttpRequestSessionServer等对象。

     

    接着执行HttpApplicationFactoryInit方法:

    1.确保网站第一次访问时调用了Global文件里的Application_Start方法;

     

     

    2.获取Global文件里的类型作为网站的HttpApplication

    3.每次返回一个HttpApplication类或子类的对象;

    a) 创建系统配置文件及用户配置的HttpModule对象,FrameWork4的系统配置文件中添加了一个HttpModuleUrlRoutingModule.循环调用Init方法,为app对象里面的某些方法事件注册方法(向请求管道里的事件注册用户的代码,完成AOP编程)

    执行HttpApplicationProcessRequest方法,内部执行“管道事件”.

    当执行到执行第七个“管道事件”,创建一个MvcHanlder,存入HttpContent

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

    1.判断浏览器URL是否有服务器文件对应,如果有,则停止方法,继续执行后面的“管道事件”,(因为js/css/jpg等不需要经过mvc处理);

    2.根据url到路由表里查找匹配url规则的路由。

    a) 遍历路由表(RouteCollection)里的所有路由,元素类型为Route,并调用每个Route对象的GetRouteData方法。

     

    b) GetRouteData方法中创建了一个RouteData对象,并将RouteMvcRouteHandler对象传进去

    i. RouteData data=new RouteData(this,this.RouteHandler)this就是Route对象,调用ProcessConstraints检查约束,如果URL不满足约束的话,直接返回Null,停止方法执行,最后将Route对象里的URL默认值和命名空间存入RouteData中,最后返回RouteData对象。

    3..接着执行RequestContext requestContext =new RequestContext(context,routeData);创建MvcHandler,并将RequestContext存入。

    IHttpHandle httpHandler=routeHandler.GetHttpHandler(requestContext);

    a) 执行routeData.GetHttpHandler方法,获取一个MvcHandler对象

    b) context.RemapHandler(httpHandler);

    其实就是将MvcHandler存入了HttpContext对象。

    当执行到第八个事件的时候:首先会检查HttpContext里的remapHanlder,发现不为空,所以不再根据url创建页面对象,直接略过,执行后面的事件。

    接着调用MvcHandlerProcessRequest方法:

    1.创建被请求的Controll类的对象,并调用里面对应的Action方法;

    2.找到视图引擎,创建对应的视图对象,视图引擎解析视图,生成Html代码。

    接着获取控制器的名称:

    1.string requiredString =this.RequestContext.RouteData.GetRequiredString(“controller”)

    2.获取一个控制器工厂对象:

    Factory =this.ControllerBuilder.GetControllerFactory();

    3.通过工厂,创建被请求的控制器类对象。

    Controller=factory.CreateController(this,RequestContext,requiredString)

    4.调用控制器父类ControllerBase里的Excute方法

    Controller.Excute(this,RequestContext);

    4.1将上下文对象设置给ControllerContext(requestContext,this);

    4.2 调用控制器里的Action方法

     

    2.开始执行ViewResultBaseExcuteResult方法,这个方法要做的是:找到视图引擎,找到视图,执行视图生成html代码。

    a) 先检查是否传入指定的视图名称,如果没有传入,则取Action方法的名字作为待会要读取的【视图名字】

    If(string.IsNullOrEmpty(this.ViewName)).this.ViewName=Context.RouteData.GetRequiredString(“action”);

    b) 找到对应的视图引擎

    ViewEngineResult result=this.FindView(context,base.ViewName,this.MasterName);

    c) 找到了RazorViewEngine对象之后,将会:

    i. 调用试图引擎的FindView方法,但这个方法在RazorViewEngine类中没有,而是在父类中定义继承关系:

    RazorViewEngine->BuildManagerViewEngine->VirtualPathProviderViewEngine

    获取控制器名称,视图的路径:

    String controllerName=controllerContext.RouteData.GetRequiredString(“controller”);

    String virePath=GetPath(controllerContext,ViewLocationFormats,AreaViewLocationFormats,”ViewLocationFormats”,viewName,controllerName,_cacheKeyPrefic_View,useCache,out viewLocationSearched);

    同时,还获得了母板页/布局页的路径

    另一种情况:

    Return  new ViewEngineResult(CreateView(controllerContext,viewPath,masterPath),this);

    返回ViewEngineResult中就包含了这个RazorView对象了。

     

    3.最终返回ViewEngineResult

    4.获取返回的ViewEngineResult里的View对象,然后调用它的Render方法来生成html代码并写入Response中。

     

     

    最后生成Html代码

     

     

  • 相关阅读:
    MyBatis代码自动生成
    英语单词--程序员专属
    动态规划小例子
    Dijkstra 算法
    矩阵变换
    (转)贝塞尔曲线
    山寨了@上位者的怜悯的样式= =
    HDU 1115 (计算多边形重心)
    HDU 1147(线段相交+链表)
    HDU 1276 (直接链表模拟)
  • 原文地址:https://www.cnblogs.com/yangda/p/2797626.html
Copyright © 2011-2022 走看看