Учитывая HttpContext (или HttpContextBase), есть ли способ получить экземпляр контроллера?
Могу ли я получить контроллер из HttpContext?
Ответ 1
HttpContext
будет содержать ссылку на MvcHandler
, которая будет содержать ссылку на RouteData
, которая будет содержать ссылку на то, какой контроллер вызывается определенным маршрутом.
NB: Это не дает вам фактического контроллера, только контроллер что конкретный маршрут будет улов.
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;
}
}
}
Этот код может выглядеть знакомым, потому что я адаптировал его из исходного кода отладки .
Ответ 2
Для тех, кто хочет получить имя контроллера, а не фактический экземпляр, как это необходимо для пользовательских переопределений авторизации AuthorizeCore (httpContext), это чистый код.
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();
Ответ 3
Не легко, вам в основном придется сначала получить MvcHandler из RouteData, а затем построить контроллер. Даже тогда он не даст вам экземпляр, используемый для обработки действия, поскольку это будет новый экземпляр контроллера.
Ответ 4
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = currentRouteData.Values["controller"].ToString();
var currentAction = currentRouteData.Values["action"].ToString();