zoukankan      html  css  js  c++  java
  • AspNet MVC中各种上下文理解

    0  前言

    AspNet MVC中比较重要的上下文,有如下:

    • 核心的上下文有HttpContext(请求上下文),ControllerContext(控制器上下文)
    • 过滤器有关有五个的上下文ActionExecutingContext,ActionExecutedContext,ResultExecutingContext,ResultExecutedContext,ExceptionContext
    • 视图相关的上下文ViewContext

    这些上下文之间的关系如下图所示

    说明:

      1、ControllerContext是对HttpContext的封装

      2、过滤器等filterContext上下文都是继承自ControllerContext

      3、ViewContext也是继承自ControllerContext,同时封装了对视图的对象

      由此可以看出,最基础还是Aspnet的HttpContext上下文贯穿整个请求/应答的,而Mvc是将HttpContext进行再次封装成ControllerContext。所以先看明白HttpContext与ControllerContext的来龙去脉即可大致了解这些上下文。

    1  HttpContext的由来

      先看看园里大叔的一张图,如下所示。

     大致的流程如下

    • AppManagerAppDomainFactory类实现IAppManagerAppDomainFactory接口的Create方法,内部实现了创建AppDomain【HttpRuntime、HttpContext等都依附在AppDomain】、HostingEnvironment等一系列操作,并且得到一个ISAPIRuntime。
    • 当IIS接受一个请求就可以通过上一步所得到的ISAPIRuntime的ProcessRequest进行处理请求。其间

       ①必须对WorkRequest针对不同的IIS版本进行包装,从而创建得到ISAPIWorkerRequest实例对象

       ②HttpRuntime调用ProcessRequestNoDemand处理上面所得到的WorkRequest,并且通过ProcessRequestInternal 实例化化请求的上下文,如下代码所示

    HttpContext context = new HttpContext(wr/WorkRequest*/, false /* initResponseWriter */);

       ③HttpContext的构造函数内部也初始化HttpRequest以及HttpResponse

      具体的内部细节,可以猛戳这里去看大叔深入剖析

    2  ControllerContext

       ControllerContext在ControllerBase的Initialize方法内部被实例化,ControllerBase作为基类,被后期控制器所继承。ControllerContext也将作为其他的过滤器上下文的基类。

    protected virtual void Initialize(RequestContext requestContext) {
                ControllerContext = new ControllerContext(requestContext, this);
            }
    
    public RequestContext RequestContext {
                get {
                    if (_requestContext == null) {
                        // still need explicit calls to constructors since the property getters are virtual and might return null
                        HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext();
                        RouteData routeData = RouteData ?? new RouteData();
    
                        _requestContext = new RequestContext(httpContext, routeData);
                    }
                    return _requestContext;
                }
                set {
                    _requestContext = value;
                }
            }
    

    3  过滤器上下文

      过滤器采用AOP(面向切面编程),可以通过实现IActionFilter,IResultFilter,IExceptionFilter,IAuthorizationFilter接口,进行附加的过滤效果。这些接口的内部方法的参数有相对应的上下文,如IActionFilter内部含有ActionExecutingContext,ActionExecutedContext上下文,而且将ControllerActionInvoker的InvokeActionMethodWithFilters内部被实例化

    public interface IActionFilter {
            void OnActionExecuting(ActionExecutingContext filterContext);
            void OnActionExecuted(ActionExecutedContext filterContext);
        }
    
    
    protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
                ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
            //省略
        
    }
    

    4  视图上下文

      视图上下文被实例化三个地方:ViewResultBase,HttpHelper、TemplateHelpers,该上下文更多的为渲染视图提供数据支持。以ViewResultBase(继承ActionResult并重写ExecuteResult方法内部对ViewContext进行实例化)为例,如下

      public override void ExecuteResult(ControllerContext context) {
                if (context == null) {
                    throw new ArgumentNullException("context");
                }
                if (String.IsNullOrEmpty(ViewName)) {
                    ViewName = context.RouteData.GetRequiredString("action");
                }
    
                ViewEngineResult result = null;
    
                if (View == null) {
                    result = FindView(context);
                    View = result.View;
                }
    
                TextWriter writer = context.HttpContext.Response.Output;
                ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
                View.Render(viewContext, writer);
    
                if (result != null) {
                    result.ViewEngine.ReleaseView(context, View);
                }
            }
    

      

    致此,基本介绍了MVC内部的上下文内容。如果觉得不错请点赞下,有误的话请指出,谢谢!

    作者:Cat Qi
    出处:http://qixuejia.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    #pragma 预处理指令
    C++类继承中的构造函数和析构函数 调用顺序
    static_cast与dynamic_cast转换 最简单的理解
    std::map的insert和下标[]访问
    C++有没有string转化int的函数,怎样转换
    c++中在一个类中定义另一个只有带参数构造函数的类的对象
    c++二进制文件的读写
    C++ 包含头文件 和 宏的使用 和 条件编译
    C++ 前置声明 和 包含头文件 如何选择
    C语言 gets()和scanf()函数的区别
  • 原文地址:https://www.cnblogs.com/LuoEast/p/7852717.html
Copyright © 2011-2022 走看看