[具有路由属性的Web API版本控制时如何获取控制器名称

问题描述 投票:4回答:1

我需要从我的路由中获取控制器名称,如果在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"];

更新:

这是我的完整选择器代码。

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;
c# asp.net-web-api asp.net-web-api-routing
1个回答
2
投票
 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;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.