如何获得控制器名称时路由attribues的Web API版本 [英] How to get controller name when Web API versioning with routing attribues

查看:140
本文介绍了如何获得控制器名称时路由attribues的Web API版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从我的路线控制器名称,这是我可以如果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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆