asp.net-mvcasp.net-mvc-2

Can I get the controller from the HttpContext?


Given an HttpContext (or HttpContextBase), is there a way to get an instance of the Controller?


Solution

  • The HttpContext will hold a reference to the MvcHandler, which will hold a reference to the RouteData, which will hold a reference to what controller is being invoked by a particular route.

    NB: This doesn't give you the actual controller, only the controller that the specific route is going to catch.

    GetController(HttpContextBase httpContext)
    {
        var routeData = ((MvcHandler)httpContext.Handler).RequestContext.RouteData;
    
        var routeValues = routeData.Values;
        var matchedRouteBase = routeData.Route;
        var matchedRoute = matchedRouteBase as Route;
    
        if (matchedRoute != null)
        {
            Route = matchedRoute.Url ?? string.Empty;
        }
    
        AssignRouteValues(httpContext, routeValues);
    }
    protected virtual VirtualPathData getVirtualPathData(HttpContextBase httpContext, RouteValueDictionary routeValues)
    {
        return RouteTable.Routes.GetVirtualPath(((MvcHandler)httpContext.Handler).RequestContext, routeValues);
    }
    
    private void AssignRouteValues(HttpContextBase httpContext, RouteValueDictionary routeValues)
    {
        var virtualPathData = getVirtualPathData(httpContext, routeValues);
    
        if (virtualPathData != null)
        {
            var vpdRoute = virtualPathData.Route as Route;
            if (vpdRoute != null)
            {
                RouteDefaults = vpdRoute.Defaults;
                RouteConstraints = vpdRoute.Constraints;
                RouteDataTokens = virtualPathData.DataTokens;
                RouteValues = routeValues;
            }
        }
    }
    

    This code may look familiar, it's because I've adapted it from Phil Haack's route debugger source code.