ASP.NET MVC 執行流程

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

 

 

相關連結:

ASP.NET MVC 1.0 - 8. TempData

Understanding the MVC Application Execution Process (C#)