4

TL;DR 摘要:我可以为 HTTP GET、PUT 和 DELETE 配置 MVC Web API 路由吗?

我一直在考虑用私有 API 替换我们旧的数据访问层(基于 DataSet 和 TableAdapters 的 DLL),以期在成功时创建公共 API。我已经使用 MVC 4 完成了一些工作来更新我们的前端,并且喜欢使用它,因此在深入研究基于 WS 或 WCF 的库之前探索“Web API”项目类型似乎是明智的。

初始演示允许我很好地返回 XML/JSON,例如:

//service.url/api/Users

...返回用户列表,而特定用户的详细信息可以通过以下方式访问:

//service.url/api/Users/99

到目前为止,如此 RESTful。但是,为了真正将 URI 映射到资源,我想对上面列出的 URI执行HTTP PUT(新用户)或HTTP DELETE (删除用户)。在我为这些项目看到的所有示例中,以及 Visual Studio 中提供的 Scaffolds 中,都遵循以下约定:

//service.url/api/Users/创建

//service.url/api/Users/Delete/99

//service.url/api/Users/Update/99

... 等等。这对我来说就像是在回避这个问题,当那里的东西被很好地组合在一起时,这是一种耻辱!

关于如何最好地解决这个问题的任何想法?

4

2 回答 2

8

你想要的是 MVC Web API 中的默认值。我不确定您在看什么,但这是将 Get/Post/Put/Delete 路由到 actions的一个很好的示例。

例如,您可能想要:

public class UsersController : ApiController
{
  // GET http://service.url/api/Users/1
  [HttpGet]
  public User GetUser(int id);

  // POST http://service.url/api/Users/?name=richard...
  [HttpPost]
  public User AddUser(User model);      

  // PUT http://service.url/api/Users/?id=1&name=Richard...
  [HttpPut]
  public User UpdateUser(User model);

  // DELETE http://service.url/api/Users/1
  [HttpDelete]
  public User DeleteUser(int id);
}

我已经明确设置了这些,但是GetUserandDeleteUser不需要前缀,因为它们以匹配的 HTTP method 开头

于 2012-12-29T18:00:59.720 回答
4

Erik 提供的链接是一个好的开始,但是当我寻找一个使用 HTTP 动词来执行这些 CRUD 操作的简单 RESTful API 时,我看到它是如何混淆这种情况的。如果您正在寻找使用 GET、PUT、POST 和 DELETE 的 HTTP 动词(可能还有 PATCH,但我在这里不介绍)并且您可以使用约定,那么以下方法将起作用:

public class UsersController : ApiController
{
    // GET http://service.url/api/Users
    public User GetAllUsers(){ ... }

    // GET http://service.url/api/Users/1
    public User GetUser(int id){ ... }

    // POST http://service.url/api/Users/
    // User model is passed in body of HTTP Request
    public User PostUser([FromBody]User model){ ... }

    // PUT http://service.url/api/Users/1
    // User model is passed in body of HTTP Request
    public User PutUser(int id, [FromBody]User model){ ... }

    // DELETE http://service.url/api/Users/1
    public User DeleteUser(int id){ ... }
}

请注意,在 Web API 中使用 HTTP 动词操作约定时,不需要方法上的属性。另外,请注意,我在 POST 和 PUT 的 User 参数上使用 [FromBody] 属性来表示正文包含我希望发送的数据。如果您尝试附加到资源,这对于 POST 可能不是最方便的,而且我还没有尝试使用 Web API 通过查询参数创建/修改数据。将您的数据放在正文中肯定会让通话感觉非常干净。“在此资源的正文中发布/放置此内容。”

另外,我在规范中阅读 PUT 的方式很可能是错误的,它充当了替代品。鉴于上面的最后一行,这也是有道理的。我将这个资源放在这个位置,替换已经存在的资源。规范 ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html ) 指出:“如果 Request-URI 指的是已经存在的资源,则封闭的实体应该被视为一个驻留在源服务器上。” 他们使用的术语是“修改过的”,所以我想这为最终用户留下了足够的解释空间。这就是 PATCH 的用武之地(https://www.rfc-editor.org/rfc/rfc5789),但目前我没有足够的信息对此发表评论。

于 2013-04-10T21:05:04.130 回答