10

在 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;

这是行不通的。

然后通过调试阅读源代码导致我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;
4

1 回答 1

13

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

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

var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
var controllerName = actions[0].ControllerDescriptor.ControllerName;
于 2013-10-24T07:53:27.937 回答