MVC的控制器的激活过程,我们从MvcHandler开始讲,前面的事情以后再讲
2020-12-13 14:35
                         标签:des   style   blog   http   color   get    我们暂时以MvcHandler为起点,至于前面谁调用了它,大家先自行研究。 系统控制权移交到MvcHandler时,这时候MVC应该说正式上场了,前面我们叫做准备工作吧。  MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState IHttpAsyncHandler, IHttpHandler定义 ASP.NET 为使用自定义 HTTP 处理程序,同时开启了session.        ControllerDescriptor MVC的控制器的激活过程,我们从MvcHandler开始讲,前面的事情以后再讲,搜素材,soscw.com MVC的控制器的激活过程,我们从MvcHandler开始讲,前面的事情以后再讲 标签:des   style   blog   http   color   get    原文地址:http://www.cnblogs.com/humble/p/3794063.html一、从MvcHandler开始(不要觉得是代码,让你看懂才是最重要的)


using Microsoft.Web.Infrastructure.DynamicValidationHelper;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Web.Mvc.Async;
using System.Web.Mvc.Properties;
using System.Web.Routing;
using System.Web.SessionState;
namespace System.Web.Mvc
{
    /// 
void IHttpHandler.ProcessRequest(HttpContext httpContext)
        {
            this.ProcessRequest(httpContext);
        }
protected virtual void ProcessRequest(HttpContext httpContext)
{
    HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
    this.ProcessRequest(httpContext2);
}
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
    IController controller;
    IControllerFactory controllerFactory;
    this.ProcessRequestInit(httpContext, out controller, out controllerFactory);//初始化工作
    try
    {
        controller.Execute(this.RequestContext);//进入主战场了
    }
    finally
    {
        controllerFactory.ReleaseController(controller);
    }
}
二、初始化
private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
    HttpContext current = HttpContext.Current;
    if (current != null && ValidationUtility.IsValidationEnabled(current) == true)
    {
        ValidationUtility.EnableDynamicValidation(current);
    }
    this.AddVersionHeader(httpContext);//httpContext 封装有关个别 HTTP 请求的所有 HTTP 特定的信息
    this.RemoveOptionalRoutingParameters();
    string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
    factory = this.ControllerBuilder.GetControllerFactory();
    controller = factory.CreateController(this.RequestContext, requiredString);//创建了一个controller 对象。
    if (controller == null)
    {
        throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[]
        {
            factory.GetType(),
            requiredString
        }));
    }
}
三、主战场
controller.Execute(this.RequestContext);//进入主战场了,controller是IController,但其实一个Controller实例,
而 Controller : ControllerBase,所以进入ControllerBase里面看看protected virtual void Execute(RequestContext requestContext)
        {
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }
            if (requestContext.HttpContext == null)
            {
                throw new ArgumentException(MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, "requestContext");
            }
            this.VerifyExecuteCalledOnce();
            this.Initialize(requestContext);
            using (ScopeStorage.CreateTransientScope())
            {
                this.ExecuteCore();//也就是调用了Controller 的ExecuteCore方法
            }
        }
protected override void ExecuteCore()
        {
            this.PossiblyLoadTempData();
            try
            {
                string requiredString = this.RouteData.GetRequiredString("action");
                if (!this.ActionInvoker.InvokeAction(base.ControllerContext, requiredString))
                {
                    this.HandleUnknownAction(requiredString);
                }
            }
            finally
            {
                this.PossiblySaveTempData();
            }
        }
public IActionInvoker ActionInvoker
{
    get
    {
        if (this._actionInvoker == null)
        {
            this._actionInvoker = this.CreateActionInvoker();
        }
        return this._actionInvoker;
    }
    set
    {
        this._actionInvoker = value;
    }
}
protected virtual IActionInvoker CreateActionInvoker()
{
    IAsyncActionInvoker arg_23_0;
    if ((arg_23_0 = this.Resolver.GetService
   // 没有异步的就看看有没有同步的,没有同步的就直接初始化一个异步的。
//这里牵扯到IOC,但系统默认的如下(DefaultDependencyResolver,把它放到了缓存中提高性能(CacheDependencyResolver )),当然可能用户自己定义。
    {
        arg_23_0 = (this.Resolver.GetService
public interface IAsyncActionInvoker : IActionInvoker
    {
        IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state);
        bool EndInvokeAction(IAsyncResult asyncResult);
    }
{
    private readonly ConcurrentDictionary
    private readonly ConcurrentDictionary
    private readonly IDependencyResolver _resolver;
    public CacheDependencyResolver(IDependencyResolver resolver)
    {
        this._resolver = resolver;
    }
    public object GetService(Type serviceType)
    {
        return this._cache.GetOrAdd(serviceType, new Func
    }
    public IEnumerableobject> GetServices(Type serviceType)
    {
        return this._cacheMultiple.GetOrAdd(serviceType, new Func
    }
}
{
    public object GetService(Type serviceType)
    {
        if (serviceType.IsInterface || serviceType.IsAbstract)
        {
            return null;
        }
        object result;
        try
        {
            result = Activator.CreateInstance(serviceType);
        }
        catch
        {
            result = null;
        }
        return result;
    }
    public IEnumerableobject> GetServices(Type serviceType)
    {
        return Enumerable.Emptyobject>();
    }
}
private sealed class CacheDependencyResolver : IDependencyResolver
        {
            private readonly ConcurrentDictionary
 
IActionInvoker,系统采用IOC创建了一个IActionInvoker对应的实例,我们不知道是什么类型,但无非AsyncControllerActionInvoker : ControllerActionInvoker
这两个(当然前者还是继承了后者)
,此处我们以ControllerActionInvoker作为讨论对象。其中的方法如下
public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(actionName))
            {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
            }
            ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(controllerContext);
            ActionDescriptor actionDescriptor = this.FindAction(controllerContext, controllerDescriptor, actionName);
            if (actionDescriptor != null)
            {
                FilterInfo filters = this.GetFilters(controllerContext, actionDescriptor);
                try
                {
                    AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor);
                    if (authorizationContext.Result != null)
                    {
                        this.InvokeActionResult(controllerContext, authorizationContext.Result);
                    }
                    else
                    {
                        if (controllerContext.Controller.ValidateRequest)
                        {
                            ControllerActionInvoker.ValidateRequest(controllerContext);
                        }
                        IDictionarystring, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor);
                        ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues);
                        this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result);
                    }
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    ExceptionContext exceptionContext = this.InvokeExceptionFilters(controllerContext, filters.ExceptionFilters, exception);
                    if (!exceptionContext.ExceptionHandled)
                    {
                        throw;
                    }
                    this.InvokeActionResult(controllerContext, exceptionContext.Result);
                }
                return true;
            }
            return false;
        }
封装描述控制器的信息,如控制器的名称、类型和操作 以及一些元数据等
 System.Object 
  System.Web.Mvc.ControllerDescriptor
    System.Web.Mvc.Async.ReflectedAsyncControllerDescriptor
    System.Web.Mvc.ReflectedControllerDescriptor下一章我们接着讲Action的执行过程
文章标题:MVC的控制器的激活过程,我们从MvcHandler开始讲,前面的事情以后再讲
文章链接:http://soscw.com/essay/34220.html