代码之家  ›  专栏  ›  技术社区  ›  zameb

当Id为字符串时,路由到多个GET失败

  •  0
  • zameb  · 技术社区  · 7 年前

    我试过回答其他类似的问题,但我仍然有这个问题。

    [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上的int约束)破坏了设置:

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

    {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}”)]将cars后面的任何字符串视为一个id,并期望像[Route(“api/cars/{id}/xxx/{yyyy}”)这样的路由来满足其他请求。但在其他过滤器之前放置一个唯一的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 回复  |  直到 7 年前
        1
  •  1
  •   farzaaaan    7 年前

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

    [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