【问题标题】:ASP.NET Web API Routing with PUT带有 PUT 的 ASP.NET Web API 路由
【发布时间】:2013-03-14 06:31:23
【问题描述】:

我正在尝试为我认为非常简单的事情设置 Web API 路由。但是,Web API 中的路由似乎与不同的 HTTP 动词不一致。假设我有具有这些操作的控制器...

public class AvalancheController : ApiControllerBase
{

    // GET api/avalanche
    public IEnumerable<Avalanche> Get() {}

    // GET api/avalanche/5
    public Avalanche Get(int id) {}

    // GET api/avalanche/ActionTest/5
    [ActionName("ActionTest")]
    public Avalanche GetActionTest(int id) {}

    // GET api/avalanche/ActionTest/2
    [ActionName("ActionTest2")]
    public Avalanche GetActionTest2(int id) {}

    // POST api/avalanche
    public void Post([FromBody]Avalanche value) {}

    // PUT api/avalanche/5
    public void Put(int id, [FromBody]Avalanche value) {}

    // PUT api/avalanche/test/5
    [ActionName("Test")]
    public void PutTest(int id, [FromBody]Avalanche value) {}

    // DELETE api/avalanche/5
    public void Delete(int id) {}
}

我定义了以下路线...

    config.Routes.MapHttpRoute(
        name: "ActionRoutes",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional },
        constraints: new
            {
                controller = "Avalanche",
                action = "(ActionTest|ActionTest2|Test)"
            }
    );


    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

然后我最终定义了以下路线...

GET api/Avalanche/ActionTest/{id}
GET api/Avalanche/ActionTest2/{id}
PUT api/Avalanche/Test/{id}
GET api/Avalanche   
POST api/Avalanche  
DELETE api/Avalanche/{id}

为什么不选择默认的 PUT 路由?默认 GET 和默认 PUT 的路由有什么不同?我已经尝试以各种可以想象的方式装饰这些功能,但我得到了相同的结果。

主要是想知道如何获取默认的 PUT 路由。如果您对如何修改这些路由有任何建议,这样我就不必为每个控制器指定一个路由来指定动作名称,那也很棒。

谢谢!

伊恩

编辑:今天早上我注意到以下路线也没有被定义..

GET api/Avalanche/{id}

【问题讨论】:

标签: asp.net asp.net-mvc asp.net-web-api-routing


【解决方案1】:

很高兴您找到了解决问题的方法。但我会根据我对 REST 服务的学习提供我的反馈。 REST webservice 的想法是将每个 url 解析为一个资源(或者可能是实体),并根据 HttpVerb 来决定操作。在这种情况下,您有三个 GET 操作,可以很好地配合您的修改。

但我认为控制器也可以重新安排为具有单一的 GET 操作并具有单一的责任,从而更好的可维护性。例如:

雪崩控制器

public class AvalancheController : ApiControllerBase
{
    public IEnumerable<Avalanche> GET()
    {

    }

    public void POST(Avalanche avalanche)
    {

    }
}

可以假设在顶层处理所有雪崩,下面是要定义的操作。

GET : 返回所有雪崩
POST:插入新的雪崩
PUT:未使用
删除:未使用

AvalancheDetailsController

public class AvalancheDetailsController : ApiControllerBase
{
    public Avalanche GET(int id)
    {

    } 


    public int PUT(int id)
    {

    }

    public int DELETE(int id)
    {

    }
}

可以假设处理单个雪崩,下面是要定义的操作。

GET : 返回单个雪崩
POST:未使用
PUT:更新单个雪崩
DELETE:删除单个雪崩

现在我假设我们对控制器有明确的区分。在您提到的 OP 中,可以有不同的 GET 操作,但它只返回单个 Avalanche。因此,我会更改 GET 方法以将对象作为输入并检查值,即,

public class AvalanceRequest
{
  public int? Id {get;set;}
  public string Name {get;set;}
}


   public class AvalancheDetailsController : ApiControllerBase
    {
        public Avalanche GET(AvalanceRequest request)
        {
           //write business logic based on parameters
           if(request.Id.HasValue)
           //return avalanche;
           if(request.Name.IsNullOrEmpty())
           //return avalanche
        } 
        //other methods
  }

处理 URL,我并没有真正使用 WebAPI,而是尝试使用 ServiceStack 来开发 REST 服务。它允许附加 url 独立于控制器名称。

网址
api/Avalanche --> AvalancheController(基于HttpVerb调用操作)
api/Avalanche/Id --> AvalancheDetailsController(基于HttpVerb调用操作)

我不知道是否可以在 WebAPI 中同样附加 url,否则您最终会获得默认配置和调用方式。 api/Avalanche 和 api/AvalancheDetails/id。

 config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

很抱歉发了这么长的帖子,希望它有意义。

【讨论】:

  • 有趣的方法。我将不得不考虑更多。这是我的第一个 REST API,所以我当然愿意接受所有想法。我一直遵循的想法是,容器将描述被操作的主要数据类型,并使用操作来描述更困难的操作。例如,如果您需要更复杂的查找来返回一组 Avalanche 项目,例如 GetAvalancheCreatedWithinDateRange(),该怎么办?每个动词都有一个功能的想法很快就被打破了。
  • @IanLee,我也在学习中。是的,在实施之前最好三思而后行。对于您的问题,由于它是 IEnumerable 上的过滤器,因此我将使用 date1 和 date2 作为 GET 方法的参数的自定义对象。但是正如你所说,可能有这么复杂的情况,我偶然发现了这篇文章,它解释了这样的实现codeproject.com/Articles/21258/…
猜你喜欢
  • 1970-01-01
  • 2015-10-09
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2019-10-21
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多