在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;
答案 0 :(得分:11)
正如@KiranChalla所证实的那样,除了使用GetSubRoutes()
var attributedRoutesData = request.GetRouteData().GetSubRoutes();
var subRouteData = attributedRoutesData.FirstOrDefault();
var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
var controllerName = actions[0].ControllerDescriptor.ControllerName;