如何获得控制器名称时路由attribues的Web API版本 [英] How to get controller name when Web API versioning with routing attribues
问题描述
我需要从我的路线控制器名称,这是我可以如果WebApiConfig使用标准的路由code做的。
不过,如果我使用路由属性,它开始变得有点艰难,尤其是试图版本时。
例如:如果我调用API /项/奖金,我有一个BonusController和BonusV2Controller和BonusV3Controller,这code返回最新控制器版本3,没关系,我可以在返回的最新和最伟大的生活版本作为默认
VAR attributedRoutesData = request.GetRouteData()GetSubRoutes()。
变种subRouteData = attributedRoutesData.FirstOrDefault();VAR行动=(ReflectedHttpActionDescriptor [])subRouteData.Route.DataTokens [行动];
//这似乎得到最新的控制器名称。 IE浏览器。 V2
controllerName =行动[0] .ControllerDescriptor.ControllerName;
现在,如果我申请一个版本1,为了简单起见,我将使用一个查询字符串,并调用API /项/奖金?V = 2
所以这code不再奏效(显然)。
我如何获得V2控制器名称?
如果我放弃路由属性和只使用WebApiConfig路由,这code工作愉快。
HttpControllerDescriptor controllerDescriptor = NULL;
变种控制器= GetControllerMapping();
变种的RouteData = request.GetRouteData();
VAR controllerName =(字符串)routeData.Values [控制器];
感谢。
更新:
下面是我的全部选择code。
的IDictionary<字符串,HttpControllerDescriptor>控制器= GetControllerMapping();VAR attributedRoutesData = request.GetRouteData()GetSubRoutes()。
变种subRouteData = attributedRoutesData.LastOrDefault(); // LastOrDefault()将获得把PeopleController,FirstOrDefault会得到人民{}版本控制器,我们不希望VAR行动=(ReflectedHttpActionDescriptor [])subRouteData.Route.DataTokens [行动];
变种controllerName =行动[0] .ControllerDescriptor.ControllerName;
//对于没有属性的路由控制器名称
// VAR controllerName =(字符串)routeData.Values [控制器];HttpControllerDescriptor oldControllerDescriptor;
如果(controllers.TryGetValue(controllerName,出oldControllerDescriptor))
{
// TODO:不同的技术来处理版本的API请求。
VAR apiVersion = GetVersionFromQueryString(请求);
//变种版本= GetVersionFromHeader(请求);
//变种版本= GetVersionFromAcceptHeaderVersion(请求);
//变种版本= GetVersionFromMediaType(请求); 如果(!String.IsNullOrEmpty(apiVersion))
{
变种newControllerName = String.Concat(controllerName,V,apiVersion); HttpControllerDescriptor newControllerDescriptor;
如果(controllers.TryGetValue(newControllerName,出newControllerDescriptor))
{
返回newControllerDescriptor;
}
}
返回oldControllerDescriptor;
}
返回null;
VAR subRouteData = request.GetRouteData()GetSubRoutes()LastOrDefault()。 如果(subRouteData = NULL&放大器;!&安培;!subRouteData.Route = NULL)
{
VAR行动= subRouteData.Route.DataTokens [行动]作为HttpActionDescriptor []; 如果(行动= NULL&放大器;!&安培; actions.Length大于0)
{
controllerName =行动[0] .ControllerDescriptor.ControllerName;
}
}
I need to get the controller name from my route and this I can do if using standard routing code in WebApiConfig.
However, if I am using routing attributes it starts to get a little difficult, especially when trying to version.
Example: If I call an api/terms/bonuses and I have a BonusController and BonusV2Controller and a BonusV3Controller, this code returns the latest controller version 3. That's ok, I can live with that returning the latest and greatest version as a default.
var attributedRoutesData = request.GetRouteData().GetSubRoutes();
var subRouteData = attributedRoutesData.FirstOrDefault();
var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
//This seems to get latest controller name. ie. V2
controllerName = actions[0].ControllerDescriptor.ControllerName;
Now if I request a version 1, for simplicity I'll use a querystring and call api/terms/bonuses?v=2
So this code no longer works (obviously).
How do I get the V2 controller name?
If I abandon routing attributes and just use WebApiConfig routing, this code works happily.
HttpControllerDescriptor controllerDescriptor = null;
var controllers = GetControllerMapping();
var routeData = request.GetRouteData();
var controllerName = (string)routeData.Values["controller"];
Thanks.
UPDATE:
Here is my full selector code.
IDictionary<string, HttpControllerDescriptor> controllers = GetControllerMapping();
var attributedRoutesData = request.GetRouteData().GetSubRoutes();
var subRouteData = attributedRoutesData.LastOrDefault(); //LastOrDefault() will get PeopleController, FirstOrDefault will get People{version}Controller which we don't want
var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
var controllerName = actions[0].ControllerDescriptor.ControllerName;
//For controller name without attribute routing
//var controllerName = (string)routeData.Values["controller"];
HttpControllerDescriptor oldControllerDescriptor;
if (controllers.TryGetValue(controllerName, out oldControllerDescriptor))
{
//TODO: Different techniques for handling version api requests.
var apiVersion = GetVersionFromQueryString(request);
//var version = GetVersionFromHeader(request);
//var version = GetVersionFromAcceptHeaderVersion(request);
//var version = GetVersionFromMediaType(request);
if (!String.IsNullOrEmpty(apiVersion))
{
var newControllerName = String.Concat(controllerName, "V", apiVersion);
HttpControllerDescriptor newControllerDescriptor;
if (controllers.TryGetValue(newControllerName, out newControllerDescriptor))
{
return newControllerDescriptor;
}
}
return oldControllerDescriptor;
}
return null;
var subRouteData = request.GetRouteData().GetSubRoutes().LastOrDefault();
if (subRouteData != null && subRouteData.Route != null)
{
var actions = subRouteData.Route.DataTokens["actions"] as HttpActionDescriptor[];
if (actions != null && actions.Length > 0)
{
controllerName = actions[0].ControllerDescriptor.ControllerName;
}
}
这篇关于如何获得控制器名称时路由attribues的Web API版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!