Avec un HttpContext (ou HttpContextBase), existe-t-il un moyen d'obtenir une instance du contrôleur?
La variable HttpContext
tiendra une référence à la variable MvcHandler
, qui contiendra une référence à la variable RouteData
, qui contiendra une référence à quel contrôleur est appelé par une route particulière.
NB: Ceci ne vous donne pas le contrôleur actuel, mais seulement le contrôleur que la route spécifique va aller capture.
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;
}
}
}
Ce code peut sembler familier, c'est parce que je l'ai adapté à partir du code source de route debugger de Phil Haack.
Pour ceux qui cherchent uniquement à obtenir le nom du contrôleur et non une instance réelle, comme cela est nécessaire pour les remplacements d'autorisations personnalisées de AuthorizeCore (httpContext), il s'agit du code vierge.
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();
Ce n’est pas facile, vous devrez au préalable obtenir le gestionnaire MvcHandler à partir de RouteData, puis construire le contrôleur. Même dans ce cas, l'instance utilisée pour gérer l'action ne vous sera pas fournie car il s'agira d'une nouvelle instance du contrôleur.
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = currentRouteData.Values["controller"].ToString();
var currentAction = currentRouteData.Values["action"].ToString();