• MVC学习笔记---各种上下文context


    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 实例化化请求的上下文,如下代码所示

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

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

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

    2  ControllerContext

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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内部被实例化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public interface IActionFilter {
            void OnActionExecuting(ActionExecutingContext filterContext);
            void OnActionExecuted(ActionExecutedContext filterContext);
        }
     
     
    protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<stringobject> parameters) {
                ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
            //省略
         
    }

    4  视图上下文

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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内部的上下文内容。如果觉得不错请点赞下,有误的话请指出,谢谢!

    原文地址:http://www.cnblogs.com/luge/p/Mvc_Context.html

  • 相关阅读:
    创建窗体不抢夺焦点的方法
    控件绘制的四种方法
    ATL CAxWindow类创建问题一则
    PE文件版本那些事儿
    GDIPlus非典型误用一例
    stl 常用代码
    For each loop in Native C++
    win7 64 下 VS2008 调试、退出时错误的解决
    DailyWallpaper v1.03 released
    编程当道,学点Python技术好傍身
  • 原文地址:https://www.cnblogs.com/changrulin/p/4840351.html
Copyright © 2020-2023  润新知