这是来自微软官方的运行原理图
当前请求到达 IIS服务器后,同样动态请求被转发到net平台,在管道执行过程中(IHttpModule),有一个特殊的IHttpModule
它就是 UrlRoutingModule ,MVC从这里就开始了。
它 根据当前的HttpContext封装HttpContextWrapper,从Route路由表中取出和当前URL匹配的路由数据(RouteData),接着生成RequestContext对象,然后创建IHttpHandler这里是MvcHandler在MvcHandler中完成了图中处理管线的所有操作。
下面从源码级分析一次请求处理流程
当请求到达路由Module时,创建MvcHandler并将封装好的RequestContext请求上下文传递给它
public MvcHandler(RequestContext requestContext)
{
if (requestContext == null)
{
throw new ArgumentNullException("requestContext");
}
RequestContext = requestContext;
}
执行MvcHandler的BeginProcessRequest方法,创建HttpContextWrapper
protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext,
AsyncCallback callback, object state)
{
HttpContextBase httpContextBase = new HttpContextWrapper(httpContext);
return BeginProcessRequest(httpContextBase, callback, state);
}
在BeginProcess中实例化了Controller并执行对应的Action等,做了很多工作,一步步来分析
protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase
httpContext, AsyncCallback callback, object state)
{
IController controller;
IControllerFactory factory;
ProcessRequestInit(httpContext, out controller, out factory);
IAsyncController asyncController = controller as IAsyncController;
if (asyncController != null)
{
// asynchronous controller
// Ensure delegates continue to use the C# Compiler static delegate caching optimization.
BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState, ProcessRequestState innerState)
{
try
{
return innerState.AsyncController.BeginExecute(innerState.RequestContext, asyncCallback, asyncState);
}
catch
{
innerState.ReleaseController();
throw;
}
};
EndInvokeVoidDelegate endDelegate = delegate(IAsyncResult asyncResult, ProcessRequestState innerState)
{
try
{
innerState.AsyncController.EndExecute(asyncResult);
}
finally
{
innerState.ReleaseController();
}
};
ProcessRequestState outerState = new ProcessRequestState()
{
AsyncController = asyncController, Factory = factory, RequestContext = RequestContext
};
SynchronizationContext callbackSyncContext = SynchronizationContextUtil.GetSynchronizationContext();
return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, outerState, _processRequestTag, callbackSyncContext: callbackSyncContext);
}
else
{
// synchronous controller
Action action = delegate
{
try
{
controller.Execute(RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
};
return AsyncResultWrapper.BeginSynchronous(callback, state, action, _processRequestTag);
}
}
在ProcessRequestInit 中,
首先在http响应报文中添加mvc版本信息
AddVersionHeader(httpContext);
从本次请求的路由数据中得到Controller(控制器)名称
//得到控制器名称
string controllerName =
RequestContext.RouteData.GetRequiredString("controller");
//从默认的控制器工厂创建控制器实例
factory = ControllerBuilder.GetControllerFactory();
controller = factory.CreateController(RequestContext, controllerName);
if (controller == null)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.ControllerBuilder_FactoryReturnedNull,
factory.GetType(),
controllerName));
}
实例化后的Controller
在这个实例化的控制器中,可以拿到很多相关的请求对象 Request Respone Model 等等,
接着如果Controller是异步则异步执行BeginExecute,否则直接执行Execute
Execute方法中执行注册的过滤器(Filter),然后通过反射调用我们的Action,执行完后返回IActionResult,这个IActionResult就是返回给客户端数据包装对象(可能不太贴切)。
处理完成后会执行factory.ReleaseController(controller); 以释放Controller
至此一次http请求在mvc中处理完毕。