【问题标题】:Get controller name获取控制器名称
【发布时间】:2013-11-01 23:28:08
【问题描述】:

在 WebApiConfig.cs 我有以下内容

public static void Register(HttpConfiguration config)
{

   config.MapHttpAttributeRoutes(); 

   config.Services.Replace(typeof(IHttpControllerSelector),
               new MyApiControllerSelector(config));

   //code omitted for brevity
}

然后在 MyApiControllerSelector.cs 我想获取控制器

public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {           
            var routeData = request.GetRouteData();           

            var controllerName = (string)routeData.Values["controller"];

            //code omitted for brevity
        }

非常简单,效果很好,但现在使用 属性路由 我认为它需要不同的方法? - 因为我似乎找不到简单的方法

我试过了

var controllerName = request.GetActionDescriptor().ControllerDescriptor.ControllerName;

这不起作用。

然后通过调试阅读source 将我带到request.GetRouteData().Values["MS_SubRoutes"]

所以现在我有

string subRoutesKey = "MS_SubRoutes";

var attributedRoutesData = routeData.Values[subRoutesKey] as IEnumerable<IHttpRouteData>; 
var subRouteData = attributedRoutesData.FirstOrDefault();

var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
var controllerName = actions[0].ControllerDescriptor.ControllerName;

哪种方法可行,但必须是更简单的方法?

更新

@KiranChalla 询问我的用例是什么,所以我发布了剩余的代码。 基本上我正在从请求中解析版本媒体类型Accept: application/vnd.app.{resource}.v{version}+json 并根据版本返回 HttpControllerDescriptor

            HttpControllerDescriptor oldControllerDescriptor;
            if (controllers.TryGetValue(controllerName, out oldControllerDescriptor))
            {
                var apiVersion = GetVersionFromMediaType(request);

                var newControllerName = String.Concat(controllerName, "V", apiVersion);

                HttpControllerDescriptor newControllerDescriptor;
                if (controllers.TryGetValue(newControllerName, out newControllerDescriptor))
                {                    
                    return newControllerDescriptor;
                }               
                return oldControllerDescriptor;
            }
            return null;

【问题讨论】:

  • 我相信没有其他我知道的更简单的方法。仅供参考...一个小改进,您可以通过request.GetRouteData().GetSubRoutes() 获取列表属性路由...
  • 顺便问一下,你能描述一下你的场景吗?我很想知道您打算如何将自定义控制器选择器与属性路由一起使用。
  • @KiranChalla 感谢您的建议。我已经解释了我的场景并添加了剩余的代码,所以如果我做错了什么,请看一下并纠正我。
  • @KiranChalla 你能看看stackoverflow.com/questions/19835015/…
  • 奇怪的是,DefaultHttpControllerSelector 有一个 GetControllerName 方法,它在子路由上也失败了。

标签: c# asp.net .net asp.net-mvc asp.net-web-api


【解决方案1】:

正如@KiranChalla 所证实的,没有比我已经实施的更简单的方法了,除了使用GetSubRoutes() 的小建议

var attributedRoutesData = request.GetRouteData().GetSubRoutes();
var subRouteData = attributedRoutesData.FirstOrDefault();

var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
var controllerName = actions[0].ControllerDescriptor.ControllerName;

【讨论】:

  • @ainteger 不,这只是从管道中获取必要数据(控制器名称)的另一种方法。
  • 使用GetSubRoutes()的建议非常好。这是我采用的方法,因为使用 MS_SubRoutes 依赖于未记录的字符串文字,将来可以轻松更改而不会发出警告。
猜你喜欢
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 2020-01-04
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多