Can I get the controller from the HttpContext?
Asked Answered
O

5

50

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

Osithe answered 14/3, 2011 at 17:59 Comment(2)
No, George Stocker's answer is as close as you will come. If you want to keep a reference to the controller in the HttpContext, you can always do so by adding a reference into your HttpContext.Items in your IControllerFactory implementation.Gorky
Not your fault poster, but it is so aggravating that every single SO post with this sort of title doesn't have any answers on how to actually get the controller (instance). The answers are always about the stupid class and action names!!!Stettin
J
32

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.

Jocosity answered 14/3, 2011 at 18:4 Comment(0)
P
107

For those looking just to get the controller name and not an actual instance, as is needed for custom authorization overrides of AuthorizeCore(httpContext), this is the clean code.

var request = httpContext.Request;
var currentUser = httpContext.User.Identity.Name;
string controller = request.RequestContext.RouteData.Values["controller"].ToString();
string action = request.RequestContext.RouteData.Values["action"].ToString();
Punctuality answered 26/1, 2012 at 17:9 Comment(1)
This doesnt give the actual method name. For example if the action name is implicit in the requestStarkey
J
32

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.

Jocosity answered 14/3, 2011 at 18:4 Comment(0)
B
4
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = currentRouteData.Values["controller"].ToString();
var currentAction = currentRouteData.Values["action"].ToString();
Bobsledding answered 14/7, 2016 at 10:12 Comment(3)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Gratify
Thanks for the suggestion. Will do it in future posts. The above code is self explanatory and I guess it doesn't requires explanationBobsledding
This answer is basically duplication of Bill's answer above (which is 4 years before you answered).Orchardist
L
2

Not easily, you will basically have to first get the MvcHandler from the RouteData, then build the Controller. Even then, it won't give you the instance used to handle the action as it will be a new instance of the controller.

Likelihood answered 14/3, 2011 at 18:9 Comment(0)
A
0

In dotnet 6:

string? controllerName = httpContext.Request.RouteValues["controller"]?.ToString();
string? actionName = httpContext.Request.RouteValues["action"]?.ToString();
Albritton answered 17/5 at 5:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.