This article describes the ASP.NET MVC request life cycle, it explains how request flows from the user browser to MVC application and vice versa.
This gives you detail description of ASP.NET MVC request steps like routing, MvcHandler, Controller, Action Execution, View Result, View Engine, and View.
ASP.NET MVC routing is nothing but matching incoming URI to action. MVC requests work on the basis of routing data which is in RouteTable. At the very first request of application RouteTable is empty. Application Start event should fill the required Routes. Depending on the URL used by the client browser UrlRoutingModule uses RouteTable to retrieve correct RouteData to define which Controller and action should be invoked.
If UrlRoutingModule gets correct RouteData, it creates RequestContext object which represent current HttpContext and RouteData. The Routing engine forwards the RequestContext object to the corresponding IRouteHandler
If UrlRoutingModule does not get a matching controller and its action for incoming the request returns the HTTP status code 404 (Page not found).
The below example shows how you can create a mapping of routes in the RegisterRoutes method called from Application Start Event.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default"
, "{controller}/{action}/{id}"
, new { controller = "Security",
action = "Login", id = UrlParameter.Optional }
);
}
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); specifies any request for .axd should be ignored and should not process.
routes.Maproute specifies route name as default and matching request should be forward to Security controller and Login method.
For each mapping, Route name should be unique. You can remove a particular route by the RouteTable.Routes.Remove(“route item”) method. See more about ASP.NET MVC routing with example
It exposes a single method GetHttpHandler, which provides RouteHandler class instance based on RouteContext data to process request. All Routes which are added to RouteTable by MapRoute extension method are handled by default RouteHandler that is MvcRouteHandler class defined in the System.Web.Mvc namespace.
Below is interface definition
public interface IRouteHandler
{
IHttpHandler GetHttpHandler(RequestContext requestContext);
}
MvcHandler is responsible for initiate actual processing of the ongoing request and generate responses. MvcHandler gets information on the current request through RequestContext object passed to its constructor.
Below is the constructor code for MVChandler
public MvcHandler(RequestContext requestContext)
{
}
MvcHandler class implements three interfaces : IHttpAsyncHandler, IHttpHandler, and IRequiresSessionState. IHTTPHandler's ProcessRequest method actually process the ongoing request.
The ProcessRequest method is implemented in MvcHandler as below
protected internal virtual
void ProcessRequest(HttpContextBase httpContext)
{
SecurityUtil.ProcessInApplicationTrust(delegate {
IController controller;
IControllerFactory factory;
this.ProcessRequestInit(httpContext, out controller, out factory);
try
{
controller.Execute(this.RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
});
}
MvcHandler uses the IControllerFactory instance and to get an IController object. All MVC controllers implement the IController interface. This interface has an Execute method that actually executes your action method code. So MVC Controller executes the method from the IController interface.
At the beginning of the Execute method, it creates a TempData object. The Execute method get Action from RouteData based on ongoing request. Then MVC Controller calls ControllerActionInvoker which creates a list of parameters coming with the URL. These parameters are collected from the request objects Parameters collection. This parameter list will be passed to the Controller Action method.
Finally, it calls the InvokeAction method to execute the action.
After the particular controller gets instantiated ActionInvoker determines which specific Action method needs to be execute. ActionInvoker uses ActionNameSelectorAttribute and ActionMethodSelectorAttribute to select Action method for execution. Action method always returns ActionResult.
If you do not want any specific method that should not accessible through public URI, you can mark that method with [NonAction] attribute.
public class ProductsController : Controller
{
public string Index()
{
return "This is Index action method of ProductController";
}
[NonAction]
public Student GetProductDetails(int ProductID)
{
return studentList.Where(s => s.ProductID == ProductID).FirstOrDefault();
}
}
If ActionResult returns a ViewResult, the execution pipeline selects the appropriate ViewEngine to render ViewResult. It is taken care of by view engine's interface IviewEngine. ASP.NET MVC has Webform and Razor view engines. You can use any of them to develop Views. You can also create your own ViewEngines and use it. For performance reasons, it is better to remove ViewEngines which are not required. For other tips on performance like Http Compession, caching visit ASP.NET website performance improvement tips. Below code clear all ViewEnginees and register only Razor.
protected void Application_Start()
{
//Remove All Engine
ViewEngines.Engines.Clear();
//Add Razor Engine
ViewEngines.Engines.Add(new RazorViewEngine());
}
The action method can return a simple string value, binary file, JSON data, or JavaScript block. And the most important is the ViewResult. It returns a response in the form of HTML which can be rendered to the browser using ViewEngine.
Action method gets required or optional user input as part of URL. Then it executes the code and prepares a response for the current request.
Each Action method controller executes either a RedirectToAction or RenderView method. The RenderView method uses a class named ViewLocator to find the corresponding View to render.
Then If there is MasterPage or ViewData then it gets set appropriately and finally the RenderView method gets called on ViewPage.