“True"通过MVC 4 Web API的REST路由

本文关键字:API Web REST 路由 MVC True quot 通过 | 更新日期: 2023-09-27 17:50:18

TL;DR摘要:我可以为HTTP GET, PUT配置MVC Web API路由吗?删除吗?

我一直在寻找替换我们旧的数据访问层(一个基于数据集和TableAdapters的DLL)与一个私有API,以创建一个公共API,如果它是成功的。我已经用MVC 4做了一些工作来刷新我们的前端,并且喜欢使用它,所以探索"Web api"似乎是明智的。在深入研究基于WS或wcf的库之前。

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

//

service.url/api/用户

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

//service.url/api/用户/99

到目前为止,非常RESTful。然而,为了真正地将URI映射到资源,我想对上面列出的URI执行HTTP PUT(新用户)或HTTP DELETE(删除用户)操作。在我所见过的这些项目的所有示例中,以及Visual Studio中提供的脚手架,都遵循以下约定:

//service.url/api/用户/创建

//service.url/api/用户/删除/99

//service.url/api/用户/更新/99

…等等......对我来说,这感觉像是在回避问题,这是一种耻辱,因为那里的东西已经很好地放在一起了!

关于如何最好地处理这个问题,有什么想法吗?

“True"通过MVC 4 Web API的REST路由

你想要的是MVC Web API的默认值。我不知道你在看什么,但这里有一个路由Get/Post/Put/Delete到动作的好例子。

例如:

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);
}

我已经明确地设置了这些,但是GetUserDeleteUser不需要前缀,因为它们以匹配的HTTP方法开始。

Erik提供的链接是一个良好的开端,但我发现,在寻找一个使用HTTP谓词执行这些CRUD操作的简单RESTful API时,它可能会使情况变得混乱。如果您希望使用HTTP动词GET、PUT、POST和DELETE(可能还有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通过查询参数创建/修改数据。它确实使调用感觉非常干净,可以将数据放置在主体中。POST/PUT此内容到此资源的正文。"

另外,我在规范中读PUT的方式,我很可能是错的,是它作为替换。考虑到上面的最后一行,这也说得通。我把这些资源放在这个位置,取代原来的资源。规范(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)声明:"如果Request-URI引用的是一个已经存在的资源,那么所包含的实体应该被认为是原始服务器上的实体的修改版本。"他们使用的术语是"修改"。所以我想这给最终用户留下了足够的解释空间。这就是PATCH的用武之地(https://www.rfc-editor.org/rfc/rfc5789),但目前我没有足够的信息对此进行评论。