带有路由属性的Web API版本控制时如何获取控制器名称 [英] How to get controller name when Web API versioning with routing attributes

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

问题描述

我需要从路由中获取控制器名称,如果在WebApiConfig中使用标准路由代码,我可以做到这一点.

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.

示例:如果我调用一个api/terms/bonuses,并且有一个BonusController和BonusV2Controller以及一个BonusV3Controller,那么这段代码将返回最新的控制器版本3.好的,我可以接受它返回的最新最大版本.默认.

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;

现在,如果我请求版本1,为简单起见,我将使用查询字符串并调用api/terms/bonuses?v = 2

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).

如何获取V2控制器名称?

How do I get the V2 controller name?

如果我放弃路由属性,而只使用WebApiConfig路由,则此代码会很愉快.

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"];

更新:

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

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;
  }
}

这篇关于带有路由属性的Web API版本控制时如何获取控制器名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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