在给定HttpContext(或HttpContextBase)的情况下,是否有一种方法可以获取Controller的实例?
在给定HttpContext(或HttpContextBase)的情况下,是否有一种方法可以获取Controller的实例?
如果只想获得控制器名称而不是实例,就像在自定义授权覆盖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();
HttpContext
将持有对 MvcHandler
的引用,MvcHandler
将持有对 RouteData
的引用,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;
}
}
}
这段代码可能看起来很熟悉,因为我是从Phil Haack的路由调试器源代码进行了修改。
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = currentRouteData.Values["controller"].ToString();
var currentAction = currentRouteData.Values["action"].ToString();
不太容易,你基本上需要先从RouteData中获取MvcHandler,然后构建Controller。即使这样做,它也不会给你用于处理操作的实例,因为它将是控制器的新实例。