如何从URL或路径数据中获取控制器类型和操作信息?

在给定System.Web.Routing.RouteData ,如何获取将被调用的控制器操作(方法)和控制器类型?

我的情况是这样的 – 我希望能够在OnActionExecuting方法中执行某些操作(或不执行)以执行操作。

但是,我经常想要知道当前的行动,而不是被称为“根”行动; 通过这个我的意思是我可能有一个名为“登录”的视图,这是我的登录页面。 该视图可以包括另一个局部视图“LeftNav”。 当为LeftNav调用OnActionExecuting ,我希望能够确定它实际上是为Login的“root”aciton调用的。

我意识到通过调用RouteTable.Routes.GetRouteData(actionExecutingContext.HttpContext) ,我可以获得“root”请求的路由,但是如何将其转换为方法和类型信息?

到目前为止,我唯一的解决方案是:

  var routeData = RouteTable.Routes.GetRouteData(actionExecutingContext.HttpContext) var routeController = (string)routeData.Values["controller"]; var routeAction = (string)routeData.Values["action"]; 

这个问题是“routeController”是删除了“Controller”后缀的控制器名称,并且不是完全限定的; 即它是“登录”,而不是“MyCode.Website.LoginController”。

如果可能的话,我宁愿得到一个实际的TypeMethodInfo ,或者至少是一个完全限定的类型名称。

有什么想法或替代方法吗?

[ 编辑 – 这是ASP.Net MVC 1.0]

  protected override void OnActionExecuting(ActionExecutingContext filterContext) { var type1 = filterContext.Controller.GetType(); var type2 = filterContext.ActionDescriptor .ControllerDescriptor.ControllerType; } 

好的,对不起,我错过了“根”部分。

然后,另一种方法,您可以将控制器类型保存到线程存储。 伪代码:

  protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (!Thread.LocalStorage.Contains("root_controller")) Thread.LocalStorage["root_controller"] = filterContext.ActionDescriptor .ControllerDescriptor.ControllerType; } 

只是一个想法。 我确信C#中提供了线程本地存储。 这里的关键思想是你只为第一次请求保存它,因此它总是根控制器。

这是我从各种来源编译的解决方案。 url变量应包含操作的URL:

  url = "YOUR URL"; // Original path is stored and will be rewritten in the end var httpContext = new HttpContextWrapper(HttpContext.Current); string originalPath = httpContext.Request.Path; try { // Fake a request to the supplied URL into the routing system httpContext.RewritePath(url); RouteData urlRouteData = RouteTable.Routes.GetRouteData(httpContext); // If the route data was not found (eg url leads to another site) then authorization is denied. // If you want to have a navigation to a different site, don't use AuthorizationMenu if(urlRouteData != null) { string controllerName = urlRouteData.Values["controller"].ToString(); string actionName = urlRouteData.Values["action"].ToString(); // Get an instance of the controller that would handle this route var requestContext = new RequestContext(httpContext, urlRouteData); var controllerFactory = ControllerBuilder.Current.GetControllerFactory(); var controller = (ControllerBase) controllerFactory.CreateController(requestContext, controllerName); // Find the action descriptor var controllerContext = new ControllerContext(httpContext, new RouteData(), controller); var controllerDescriptor = new ReflectedControllerDescriptor(controller.GetType()); var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); } } finally { // Reset our request path. httpContext.RewritePath(originalPath); } 
 public Type ControllerType(string controllerName) { var fullName = controllerName + "Controller"; var assemblyName = Assembly.GetExecutingAssembly().FullName; return Activator.CreateInstance(assemblyName, fullTypeName).GetType(); } public MethodInfo ActionMethodInfo(string actionName, Type controllerType) { return controllerType.GetMethod(actionName); } 

您是否正在考虑类似于此的实现? 需要一些尝试/捕获!

善良,

MvcSiteMapProvider这样做。 这是这个特殊事物的代码。

这是代码