ASP.NET MVC 執行流程
1. 從應用程式端接收第一個要求(Applicantion Start)
Global.asax建立路由表(RouteTable)
2. 執行路由
UrlRoutingModule會使用第一個符合在路由表內的路由建立RouteData,並建立RequestContext(IHttpContext)物件。
3. 建立MVC要求處理者
MvcRouteHandler物件會建立一個MvcHandler,並且把RequestContext傳給MvcHandler
4. 建立Controller
MvcHandler使用RequestContext讓IControllerFactory(預設DefaultControllerFactory)決定要建立哪一個Controller。
5. 執行Controller
MvcHandler呼叫Controller Execute方法,並傳入RequestContext,透過Initialize建立ControllerContext
public class MvcHandler : IHttpHandler, IRequiresSessionState
{
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
this.AddVersionHeader(httpContext);
string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
IControllerFactory controllerFactory = this.ControllerBuilder.GetControllerFactory();
IController controller = controllerFactory.CreateController(this.RequestContext, requiredString);
if (controller == null)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, MvcResources.ControllerBuilder_FactoryReturnedNull,
new object[] { controllerFactory.GetType(), requiredString }));
}
try
{
controller.Execute(this.RequestContext);
}
finally
{
controllerFactory.ReleaseController(controller);
}
}
}
public abstract class ControllerBase : MarshalByRefObject, IController
{
protected virtual void Execute(RequestContext requestContext)
{
if (requestContext == null)
{
throw new ArgumentNullException("requestContext");
}
this.Initialize(requestContext);
this.ExecuteCore();
}
protected virtual void Initialize(RequestContext requestContext)
{
this.ControllerContext = new ControllerContext(requestContext, this);
}
}
6. 呼叫動作(Action)
大部份的Controllers都繼承自Controller(繼承自ControllerBase),當Controllers都有繼承的時候,ControllerActionInvoker會決定要呼叫哪一個動作方法,並且執行。
protected override void ExecuteCore()
{
base.TempData.Load(base.ControllerContext, this.TempDataProvider);
try
{
string requiredString = this.RouteData.GetRequiredString("action");
if (!this.ActionInvoker.InvokeAction(base.ControllerContext, requiredString))
{
this.HandleUnknownAction(requiredString);
}
}
finally
{
base.TempData.Save(base.ControllerContext, this.TempDataProvider);
}
}
這邊額外提一下:
ControllerBase中存在一個叫做TempData的Property,型別是TempDataDictionary。而TempData很適合用來在Action之傳遞資料,而且很簡省資源。(但需啟用SessionState)
和ViewData不同的地方是:ViewData每次使用時會重新建立,而TempData會從Session載入(但如果本次沒有更新則該項目會移除)。
所以一般顯示資料或訊息的時候請使用ViewData,而需要重新導向別的Action則使用TempData。
想要詳細了解的人可以參考底下的相關連結。
7. 執行結果(ActionResult)
執行結果包含了:
ViewResult -- View
RedirectToRouteResult -- RedirectToAction or RedirectToAction
RedirectResult – Redirect
ContentResult – Content
JsonResult – Json
EmptyResult
相關連結:
Understanding the MVC Application Execution Process (C#)