繁体   English   中英

Web Api 2 API无法识别路由的多个属性(版本控制)

[英]Web Api 2 API not recognizing Multiple Attributes for Routing (Versioning)

我正在尝试从RoutingConstaints Sample实现属性路由VersionedRoute ,但是当我在控制器上使用两者时,版本化属性不再起作用。

我需要在属性上修改什么才能让它与属性路由一起使用?

对于代码示例,请下载示例项目(或者只查看上面链接中的几个文件),然后修改路由:

// When I use the RoutePrefix, VersionedRoute no longer works (Sending "Api-Version" through http header doesn't route correctly
// If I remove the RoutePrefix I can use VersionedRoute again
// What do I need to change in its code to be able to use both?

[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1"
[RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers
public class CustomersV1Controller : ApiController {

    /* Other stuff removed */

    [VersionedRoute("api/Customer", 1)] // I'd rather not have to use this here at all and just use a single one on the class, but having both nor just one on either works right now.
    [Route("")]
    public IHttpActionResult Get()
    {
        return Json(_customers);
    }
}

VersionedRoute代码

VersionConstraint代码

编辑:如果您需要更多信息,甚至发布想法或事情,请告诉我:)

编辑2:以下是我试图从特洛伊亨特的博客做的一个例子: http//www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html

Edit3:这是我想要编写的代码,因为它会减少很多开销和魔术字符串。

[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1"
[RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers
public class CustomersV1Controller : ApiController {

    /* Other stuff removed */
    [Route("")]
    public IHttpActionResult Get()
    {
        // Removed
        return Ok(customers);
    }


    [Route("{id:int}")]
    public IHttpActionResult GetById(int id)
    {
        // Removed
        return Ok(customer);
    }
}

[VersionedRoute("api/Customers", 2)] // This route would be used as http://url/api/customers with a header of "api-version: 2"
[RoutePrefix("api/v2/Customers")] // This route would be used purely through url versioning of http://url/api/v2/Customers
public class CustomersV2Controller : ApiController {

    /* Other stuff removed */
    [Route("")]
    public IHttpActionResult Get()
    {
        // Removed
        return Ok(customersThatAreDifferentThanV1);
    }


    [Route("{id:int}")]
    public IHttpActionResult GetById(int id)
    {
        // Removed
        return Ok(customerThatIsDifferent);
    }
}

编辑:最后一次尝试,只需要在每个路由上编写一次路由版本信息,在控制器属性级别而不是每次操作。

RouteVersionedRoute属性一起正常工作,但您的RoutePrefix属性也适用于您的VersionedRoute (尝试访问/ api / v1 / Customers / api / Customer - 当设置api-version标头时,您将收到响应)

以下代码将针对示例中返回正确响应的两个URL产生所需的行为,但显然这并不能解决您想要在类顶部使用一个VersionedRoute和一个RoutePrefix问题。 为此需要另一种方法。 但是,您可以为不同的api版本提供单独的控制器。

[RoutePrefix("api")]
public class CustomersV1Controller : ApiController
{
    /* Other stuff removed */

    [VersionedRoute("Customers", 1)]
    [Route("v1/Customers")]
    public IHttpActionResult Get()
    {
        return Json(_customers);
    }
}

改进是创建自己的属性而不是Route这样您就不需要每次都为版本添加前缀:

public class CustomVersionedRoute : Attribute, IHttpRouteInfoProvider
{
    private readonly string _template;

    public CustomVersionedRoute(string route, int version)
    {
        _template = string.Format("v{0}/{1}", version, route);
    }

    public string Name { get { return _template; } }
    public string Template { get { return _template ; } }
    public int Order { get; set; }
}

[RoutePrefix("api")]
public class CustomersV2Controller : ApiController
{
    /* Other stuff removed */

    [VersionedRoute("Customers", 2)]
    [CustomVersionedRoute("Customers", 2)]
    public IHttpActionResult Get()
    {
        return Json(_customers);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM