代码之家  ›  专栏  ›  技术社区  ›  Rob Levine

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

  •  10
  • Rob Levine  · 技术社区  · 14 年前

    如果给定 System.Web.Routing.RouteData ?

    我的场景是这样的-我希望能够在 OnActionExecuting 操作的方法。

    但是,我经常想知道的不是当前的操作,而是正在调用的“根”操作;我的意思是我可能有一个名为“登录”的视图,这是我的登录页面。此视图可能包括 另一个局部视图“leftnav”。什么时候? 操作执行 是为leftnav调用的,我想能够确定它确实是为登录的“根”调用的。

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

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

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

    问题在于“routecontroller”是删除了“controller”后缀的控制器名称,并且不是完全限定的;即它是“login”,而不是“mycode.website.login controller”。

    我宁愿得到一个真实的 Type MethodInfo 如果可能,或者至少是完全限定的类型名。

    有什么想法,或者其他方法吗?

    [ 编辑 -这是ASP.NET MVC 1.0]

    4 回复  |  直到 10 年前
        1
  •  5
  •   queen3    14 年前
      protected override void OnActionExecuting(ActionExecutingContext filterContext)
      {
         var type1 = filterContext.Controller.GetType();
         var type2 = filterContext.ActionDescriptor
                        .ControllerDescriptor.ControllerType;
      }
    

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

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

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

    只是一个想法。我确信线程本地存储在C中可用。这里的关键思想是只为第一个请求保存它,因此它始终是根控制器。

        2
  •  4
  •   VitalyB    11 年前

    下面是我从各种来源编译的解决方案。这个 网址 变量应包含操作的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 (e.g 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);
            }
    
        3
  •  1
  •   Daniel Elliott    14 年前
    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);
    }
    

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

    仁慈,

        4
  •  0
  •   Orlando Osorio    10 年前

    MVCSitemApprovider执行此操作。这是这件事的代码。

    Here is the code