在过滤器属性中获取区域、控制器和动作名称
Getting area, controller and action names inside filter attributes
我有全局属性,我需要知道其中的区域、控制器和操作。由于路由(内部区域注册和属性路由),我无法使用 RawUrl。我遵循了以下两种方法,但在这两种情况下,我的区域都返回为空。当我使用路线时,我就可以很好地获得区域名称。为什么当我执行 redirecttoaction 或 url.action 或手动输入 url 等时我的区域为空?我们正在使用 MVC 5.0。
1:
var routingValues = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current)).Values;
var currentArea = (string) routingValues["area"] ?? string.Empty;
var currentController = (string) routingValues["controller"] ?? string.Empty;
var currentAction = (string) routingValues["action"] ?? string.Empty;
2:
var handler = HttpContext.Current.Handler as System.Web.Mvc.MvcHandler;
var area = handler.RequestContext.RouteData.Values["area"];
var controller = handler.RequestContext.RouteData.Values["controller"];
var action = handler.RequestContext.RouteData.Values["action"];
就像我上面说的,如果我使用路线 (/TipHotLine),那么我就可以很好地获取区域名称。
public class AgencyAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Agency";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Agency_default",
"Agency/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"tiphotline",
"tiphotline",
new
{
controller = "tiphotline",
action = "Index",
Area = "Agency"
}
);
}
}
注册区域时,使用的 MapRoute 方法会向每条路线添加 dataContextToken。你可以查看源代码here,你会看到一个类似下面的方法,你会注意到一行添加了数据令牌:
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces)
{
...
route.DataTokens[RouteDataTokenKeys.Area] = AreaName;
...
return route;
}
因此,在您的过滤器中,您只需要使用键 "area"
而不是路由值来获取数据令牌。例如,以下过滤器将添加 header 在路线
中找到的区域、控制器和操作
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var routingValues = filterContext.RouteData.Values;
var currentArea = filterContext.RouteData.DataTokens["area"] ?? string.Empty;
var currentController = (string)routingValues["controller"] ?? string.Empty;
var currentAction = (string)routingValues["action"] ?? string.Empty;
filterContext.HttpContext.Response.AddHeader("Routing info", string.Format("controller={0},action={1},area={2}", currentController, currentAction, currentArea));
}
我有全局属性,我需要知道其中的区域、控制器和操作。由于路由(内部区域注册和属性路由),我无法使用 RawUrl。我遵循了以下两种方法,但在这两种情况下,我的区域都返回为空。当我使用路线时,我就可以很好地获得区域名称。为什么当我执行 redirecttoaction 或 url.action 或手动输入 url 等时我的区域为空?我们正在使用 MVC 5.0。
1:
var routingValues = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current)).Values;
var currentArea = (string) routingValues["area"] ?? string.Empty;
var currentController = (string) routingValues["controller"] ?? string.Empty;
var currentAction = (string) routingValues["action"] ?? string.Empty;
2:
var handler = HttpContext.Current.Handler as System.Web.Mvc.MvcHandler;
var area = handler.RequestContext.RouteData.Values["area"];
var controller = handler.RequestContext.RouteData.Values["controller"];
var action = handler.RequestContext.RouteData.Values["action"];
就像我上面说的,如果我使用路线 (/TipHotLine),那么我就可以很好地获取区域名称。
public class AgencyAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Agency";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Agency_default",
"Agency/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"tiphotline",
"tiphotline",
new
{
controller = "tiphotline",
action = "Index",
Area = "Agency"
}
);
}
}
注册区域时,使用的 MapRoute 方法会向每条路线添加 dataContextToken。你可以查看源代码here,你会看到一个类似下面的方法,你会注意到一行添加了数据令牌:
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces)
{
...
route.DataTokens[RouteDataTokenKeys.Area] = AreaName;
...
return route;
}
因此,在您的过滤器中,您只需要使用键 "area"
而不是路由值来获取数据令牌。例如,以下过滤器将添加 header 在路线
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var routingValues = filterContext.RouteData.Values;
var currentArea = filterContext.RouteData.DataTokens["area"] ?? string.Empty;
var currentController = (string)routingValues["controller"] ?? string.Empty;
var currentAction = (string)routingValues["action"] ?? string.Empty;
filterContext.HttpContext.Response.AddHeader("Routing info", string.Format("controller={0},action={1},area={2}", currentController, currentAction, currentArea));
}