Nov 9, 2009

Context data in asp.net mvc

Along the asp.net mvc stack, there are lots context data being passing around. The first context data is passed into MvcRouteHandler by the System.Web.Routing.UrlRoutingModule.

public class RequestContext
{
    public RequestContext(HttpContextBase httpContext, RouteData routeData);

    public HttpContextBase HttpContext { get; }
    public RouteData RouteData { get; }
}

Then the RequestContext is passed into MvcHandler via constructor. When MvcHandler.ProcessRequest is called, it wrap the httpContext into HttpContextBase, which is System.Web.Abstractions class. The reason to use HttpContext to replace the dependency on HttpContext object, which is sealed, with dependency on HttpContextBase which is an abstraction.

//MvcHandler member
public MvcHandler(RequestContext requestContext) {
    if (requestContext == null) {
        throw new ArgumentNullException("requestContext");
    }
    RequestContext = requestContext;
}

protected virtual void ProcessRequest(HttpContext httpContext) {
    HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
    ProcessRequest(iHttpContext);
}

protected internal virtual void ProcessRequest(HttpContextBase httpContext) {
 //skip
 IController controller = factory.CreateController(RequestContext, controllerName);
 //skip
  controller.Execute(RequestContext);
}

When creating Controller, the RequestContext is passed into the ControllerFactory.CreateController method, after the controller is created the RequestContext is passed into controller.Execute method. By default, the controller is a System.Web.Mvc.Controller. A ControllerContext is created based on the RequestContext, the controller itself. A UrlHelper is also created with RequestContext. So nowt the Controller has a ControllerContext, and UrlHelper.

//Controller member
protected override void Initialize(RequestContext requestContext) {
    base.Initialize(requestContext);
    Url = new UrlHelper(requestContext);
}
//ControllerBase member
protected virtual void Initialize(RequestContext requestContext) {
    ControllerContext = new ControllerContext(requestContext, this);
}

Then ControllerContext is used to create ControllerDescriptor, and ActionDescriptor, and FilterInfo(Filters), AuthorizationContext, parameters for actio method. ActionExecutedContext. It is also used in InvokeActionResultWithFilters method. Eventually, ActionResult use ControllerContext to ExecuteResult. ContextController is used to find ViewEngineResult

public abstract class ActionResult {

    public abstract void ExecuteResult(ControllerContext context);

}

A ViewContext is created by using ControllerContext, and IView use viewContext to render view. ViewContext.ViewData is passed into ViewPage or ViewUserControl