【发布时间】:2011-07-15 05:14:32
【问题描述】:
给定一个 HttpContext(或 HttpContextBase),有没有办法获取 Controller 的实例?
【问题讨论】:
-
不,George Stocker 的答案与您的答案一样接近。如果您想在 HttpContext 中保留对控制器的引用,您始终可以通过在您的
IControllerFactory实现中向您的HttpContext.Items添加引用来实现。
给定一个 HttpContext(或 HttpContextBase),有没有办法获取 Controller 的实例?
【问题讨论】:
IControllerFactory 实现中向您的 HttpContext.Items 添加引用来实现。
对于那些只想获取控制器名称而不是实际实例的用户,这是 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 的引用,后者将持有对特定路由正在调用的控制器的引用。
注意:这并没有给你实际的控制者,只有控制者 具体路线要去 抓住。
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 的 route debugger 源代码。
【讨论】:
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = currentRouteData.Values["controller"].ToString();
var currentAction = currentRouteData.Values["action"].ToString();
【讨论】:
不容易,基本上你必须先从 RouteData 中获取 MvcHandler,然后再构建 Controller。即使那样,它也不会为您提供用于处理操作的实例,因为它将是控制器的新实例。
【讨论】: