当Id是字符串时,路由到多个GETS失败

时间:2017-09-29 16:27:58

标签: c# rest asp.net-web-api-routing

我已经尝试过其他类似问题的答案,但我仍然遇到这个问题。 我们正在使用如下设置实现ASP.NET REST API:

[Authorize]
[Route("api/cars/{id:int}")]
public HttpResponseMessage Get(int id)
{
    //Some stuff
}

[Authorize]
[Route("api/cars/{brand?}/{color?}")]
public HttpResponseMessage GetBySource(string brand = null, string color = null)
{
    //Some stuff
}

由于Get(int id)方法的int约束,路由工作正常,它支持调用:

{host}/api/cars/1
{host}/api/cars/toyota
{host}/api/cars/toyota/blue
{host}/api/cars?brand=toyota&color=blue

现在有了支持字符串ID的新要求 以下"逻辑"更改(删除Id上的int约束)已破坏设置:

[Authorize]
[Route("api/cars/{id}")]
public HttpResponseMessage Get(string id)
{
    //Some stuff
}

现在,大多数先前的调用都被路由到Get(字符串ID):

{host}/api/cars/1             //---> Works OK
{host}/api/cars/toyota        //---> "toyota" is the car Id instead of brand (No OK)
{host}/api/cars?brand=toyota  //---> "brand=toyota" is the car Id instead of parsing the brand (No OK)
{host}/api/cars/toyota/blue   //---> (404 Error)
{host}/api/cars?brand=toyota&color=blue  //---> (404 Error)

毕竟它有道理。 [Route(" api / cars / {id}")]正在考虑将汽车作为Id之后的任何字符串,并期待像[Route(" api / cars / {id)这样的路线} / xxx / {yyy}")]以适应其他请求。但是在其他过滤器之前放置一个唯一的ID是没有意义的。

我们正在评估只有在真正需要时才改变我们之前的设计。所以我的问题是: 我们可以进行以下设计工作吗?:

{host}/api/cars/A100T50
{host}/api/cars/toyota
{host}/api/cars/toyota/blue
{host}/api/cars?brand=toyota&color=blue

如果没有,您建议我使用哪种设计?

我的路线配置很简单:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
}

提前感谢任何指导

1 个答案:

答案 0 :(得分:1)

你能将两种方法结合起来吗?

[Authorize]
//edit: add another route so that it recognizes id 
[Route("api/cars/{id}")]
[Route("api/cars")]
public HttpResponseMessage Get(string brand = "", string color = "", string id = "")
{
    //example to get from database based on whichever parameter provided 
    using(var ctx = new DbContext())
    {
        var cars = ctx.Cars
                      .Where(car => String.IsNullOrEmpty(id) || car.Id == id 
                      && String.IsNullOrEmpty(color) || car.Color == color
                      && String.IsNullOrEmpty(brand) || car.Brand == brand);
    //Some stuff
}

你可以打电话

{host}/api/cars/AT100
{host}/api/cars?id=AT100
{host}/api/cars?color=black