我需要从我的路由中获取控制器名称,如果在 WebApiConfig 中使用标准路由代码,我可以做到这一点。
但是,如果我使用路由属性,它就会开始变得有点困难,尤其是在尝试版本控制时。
示例:如果我调用 api/terms/bonuses,并且我有 BonusController、BonusV2Controller 和 BonusV3Controller,则此代码将返回最新的控制器版本 3。没关系,我可以接受默认返回最新和最好的版本。
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;
现在,如果我请求版本 1,为了简单起见,我将使用查询字符串并调用 api/terms/bonuses?v=2
所以这段代码不再有效(显然)。
如何获取 V2 控制器名称?
如果我放弃路由属性并仅使用 WebApiConfig 路由,则此代码可以正常工作。
HttpControllerDescriptor controllerDescriptor = null;
var controllers = GetControllerMapping();
var routeData = request.GetRouteData();
var controllerName = (string)routeData.Values["controller"];
UPDATE:
这是我的完整选择器代码。
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;