一、从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 { ///Selects the controller that will handle an HTTP request. public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState { private static readonly object _processRequestTag = new object(); internal static readonly string MvcVersion = MvcHandler.GetMvcVersionString(); /// Contains the header name of the ASP.NET MVC version. public static readonly string MvcVersionHeaderName = "X-AspNetMvc-Version"; private ControllerBuilder _controllerBuilder; internal ControllerBuilder ControllerBuilder { get { if (this._controllerBuilder == null) { this._controllerBuilder = ControllerBuilder.Current; } return this._controllerBuilder; } set { this._controllerBuilder = value; } } /// Gets or sets a value that indicates whether the MVC response header is disabled. /// true if the MVC response header is disabled; otherwise, false. public static bool DisableMvcResponseHeader { get; set; } /// Gets a value that indicates whether another request can use the instance. /// true if the instance is reusable; otherwise, false. protected virtual bool IsReusable { get { return false; } } /// Gets the request context. /// The request context. public RequestContext RequestContext { get; private set; } /// Gets a value that indicates whether another request can use the instance. /// true if the instance is reusable; otherwise, false. bool IHttpHandler.IsReusable { get { return this.IsReusable; } } /// Initializes a new instance of the class. /// The request context. /// The parameter is null. public MvcHandler(RequestContext requestContext) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } this.RequestContext = requestContext; } /// Adds the version header by using the specified HTTP context. /// The HTTP context. protected internal virtual void AddVersionHeader(HttpContextBase httpContext) { if (!MvcHandler.DisableMvcResponseHeader) { httpContext.Response.AppendHeader(MvcHandler.MvcVersionHeaderName, MvcHandler.MvcVersion); } } /// Called by ASP.NET to begin asynchronous request processing. /// The status of the asynchronous call. /// The HTTP context. /// The asynchronous callback method. /// The state of the asynchronous object. protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) { HttpContextBase httpContext2 = new HttpContextWrapper(httpContext); return this.BeginProcessRequest(httpContext2, callback, state); } /// Called by ASP.NET to begin asynchronous request processing using the base HTTP context. /// The status of the asynchronous call. /// The HTTP context. /// The asynchronous callback method. /// The state of the asynchronous object. protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) { IController controller; IControllerFactory factory; this.ProcessRequestInit(httpContext, out controller, out factory); IAsyncController asyncController = controller as IAsyncController; if (asyncController != null) { BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { IAsyncResult result; try { result = asyncController.BeginExecute(this.RequestContext, asyncCallback, asyncState); } catch { factory.ReleaseController(asyncController); throw; } return result; }; EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { try { asyncController.EndExecute(asyncResult); } finally { factory.ReleaseController(asyncController); } }; SynchronizationContext synchronizationContext = SynchronizationContextUtil.GetSynchronizationContext(); AsyncCallback callback2 = AsyncUtil.WrapCallbackForSynchronizedExecution(callback, synchronizationContext); return AsyncResultWrapper.Begin(callback2, state, beginDelegate, endDelegate, MvcHandler._processRequestTag); } Action action = delegate { try { controller.Execute(this.RequestContext); } finally { factory.ReleaseController(controller); } }; return AsyncResultWrapper.BeginSynchronous(callback, state, action, MvcHandler._processRequestTag); } /// Called by ASP.NET when asynchronous request processing has ended. /// The asynchronous result. protected internal virtual void EndProcessRequest(IAsyncResult asyncResult) { AsyncResultWrapper.End(asyncResult, MvcHandler._processRequestTag); } private static string GetMvcVersionString() { return new AssemblyName(typeof(MvcHandler).Assembly.FullName).Version.ToString(2); } /// Processes the request by using the specified HTTP request context. /// The HTTP context. protected virtual void ProcessRequest(HttpContext httpContext) { HttpContextBase httpContext2 = new HttpContextWrapper(httpContext); this.ProcessRequest(httpContext2); } /// Processes the request by using the specified base HTTP request context. /// The HTTP context. 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); this.RemoveOptionalRoutingParameters(); string requiredString = this.RequestContext.RouteData.GetRequiredString("controller"); factory = this.ControllerBuilder.GetControllerFactory(); controller = factory.CreateController(this.RequestContext, requiredString); if (controller == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[] { factory.GetType(), requiredString })); } } private void RemoveOptionalRoutingParameters() { RouteValueDictionary values = this.RequestContext.RouteData.Values; string[] array = ( from entry in values where entry.Value == UrlParameter.Optional select entry.Key).ToArray<string>(); string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string key = array2[i]; values.Remove(key); } } /// Enables processing of HTTP Web requests by a custom HTTP handler that implements the interface. /// An object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) that are used to service HTTP requests. void IHttpHandler.ProcessRequest(HttpContext httpContext) { this.ProcessRequest(httpContext); } /// Called by ASP.NET to begin asynchronous request processing using the base HTTP context. /// The status of the asynchronous call. /// The HTTP context. /// The asynchronous callback method. /// The data. IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { return this.BeginProcessRequest(context, cb, extraData); } /// Called by ASP.NET when asynchronous request processing has ended. /// The asynchronous result. void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) { this.EndProcessRequest(result); } } }
我们暂时以MvcHandler为起点,至于前面谁调用了它,大家先自行研究。
系统控制权移交到MvcHandler时,这时候MVC应该说正式上场了,前面我们叫做准备工作吧。
MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
IHttpAsyncHandler, IHttpHandler定义 ASP.NET 为使用自定义 HTTP 处理程序,同时开启了session.
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() ) == null)//
// 没有异步的就看看有没有同步的,没有同步的就直接初始化一个异步的。
//这里牵扯到IOC,但系统默认的如下(DefaultDependencyResolver,把它放到了缓存中提高性能(CacheDependencyResolver )),当然可能用户自己定义。 { arg_23_0 = (this.Resolver.GetService() ?? new AsyncControllerActionInvoker()); } return arg_23_0; }
public interface IAsyncActionInvoker : IActionInvoker
{
IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state);
bool EndInvokeAction(IAsyncResult asyncResult);
}
private sealed class CacheDependencyResolver : IDependencyResolver
{
private readonly ConcurrentDictionaryobject> _cache = new ConcurrentDictionaryobject>();
private readonly ConcurrentDictionaryobject>> _cacheMultiple = new ConcurrentDictionaryobject>>();
private readonly IDependencyResolver _resolver;
public CacheDependencyResolver(IDependencyResolver resolver)
{
this._resolver = resolver;
}
public object GetService(Type serviceType)
{
return this._cache.GetOrAdd(serviceType, new Funcobject>(this._resolver.GetService));
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this._cacheMultiple.GetOrAdd(serviceType, new Funcobject>>(this._resolver.GetServices));
}
}
{
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 IEnumerable<object> GetServices(Type serviceType)
{
return this._cacheMultiple.GetOrAdd(serviceType, new Func
}
}
this.InnerSetResolver(new DependencyResolver.DefaultDependencyResolver());
private class DefaultDependencyResolver : IDependencyResolver
{
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 IEnumerable<object> GetServices(Type serviceType)
{
return Enumerable.Empty<object>();
}
}
{
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 IEnumerable<object> GetServices(Type serviceType)
{
return Enumerable.Empty<object>();
}
}
private sealed class CacheDependencyResolver : IDependencyResolver { private readonly ConcurrentDictionaryobject> _cache = new ConcurrentDictionary object>(); private readonly ConcurrentDictionary object>> _cacheMultiple = new ConcurrentDictionary object>>(); private readonly IDependencyResolver _resolver; public CacheDependencyResolver(IDependencyResolver resolver) { this._resolver = resolver; } public object GetService(Type serviceType) { return this._cache.GetOrAdd(serviceType, new Func object>(this._resolver.GetService)); } public IEnumerable<object> GetServices(Type serviceType) { return this._cacheMultiple.GetOrAdd(serviceType, new Func object>>(this._resolver.GetServices)); }
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); } IDictionary<string, 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; }
ControllerDescriptor
封装描述控制器的信息,如控制器的名称、类型和操作 以及一些元数据等
System.Object
System.Web.Mvc.ControllerDescriptor
System.Web.Mvc.Async.ReflectedAsyncControllerDescriptor
System.Web.Mvc.ReflectedControllerDescriptor