你现在拥有什么
要使用上述方法,您需要使用 RPC。这是因为您的示例已经一半沉浸在 RPC 风格的处理中。默认 WebAPI 路由鼓励 RESTful 设置,但如果您对路由进行微小的更改,一切都会开始工作。例如,您可以将默认路由更改为典型的 MVC 路由:
routes.MapRoute( name : "Default",
url : "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional });
添加路由后,以典型的 MVC 方式调用,其中使用控制器名称和操作。然而,从你的问题来看,我怀疑你实际上想要 RESTful,而不是仅仅让它工作,所以请继续阅读......
保持安静
REST 不需要 HTTP http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven,尽管两者经常被放在一起讨论。 REST 实际上是关于每个资源都具有语义上准确的表示。当使用 HTTP 时,这意味着尊重 HTTP 语义的唯一 URI。例如,使用 HTTP GET 的调用永远不应该修改数据,因为这违反了 HTTP 的 GET 定义并混淆了 HTTP 基础设施(如缓存)。
POST/PUT 与 MERGE/PATCH
我们都熟悉 GET、POST、PUT、HEAD 等 HTTP 方法。一般来说,GET 用于检索,POST 用于添加,PUT 用于修改(尽管存在很多争论)。然而,您有两种类型的修改:添加项目和从集合中删除项目。那么这些都是 PUT 还是其他什么?社区还没有完全解决 http://www.dehora.net/journal/2009/02/03/just-use-post/关于如何做到这一点。
选项 1:自定义媒体类型- HTTP 规范确实允许各种方法,但浏览器真正将我们限制在熟悉的子集上。所以你可以创建MERGE(Roy Fielding 的解决方法)或 PATCH(oData 的解决方法) https://stackoverflow.com/questions/2443324/best-practice-for-partial-updates-in-a-restful-service方法并定义这种新媒体类型的行为——可能一个用于添加,一个用于删除。
选项 2:使用 POST/PUT- 使用 PUT 添加和删除联系人。只需将 ID 列表视为切换开关(如果存在则删除,如果缺少则添加),或者交替包含足够的信息以了解要做什么。然后返回 HTTP 303,向客户端表明其状态已过时并进行刷新。
选项 3:完整列表- 如果您的集合大小合理,您每次想要更新时都可以传递完整的联系人列表。这种方式的逻辑是超级简单的擦除和替换。
从 RESTful 角度来看,真正重要的是您的应用程序在所有方法中都以一致的方式运行。因此,如果 MERGE 意味着添加,那么它应该始终意味着添加。如果您希望将一组完整的 ID 传递给 PUT,则始终传递一组完整的 ID。
控制器设计
如果是我,我会把你的控制器分成多个控制器。一个控制器处理组,另一个控制器处理联系人(作为一个组),第三个控制器处理组内的一个联系人。就像是 ...
//api/Group/
public List<GroupModel> Get()
public GroupModel Get(int ID)
public GroupModel Post(GroupModel model) //add a group
public GroupModel Put(GroupModel model) //update a group (see comments above)
public void Delete(int ID)
//api/GroupContacts/
public ContactsModel Get() //gets complete list
public void PostContacts(ContactsModel model) //pushes a COMPLETE new state
public void Delete() //delete entire group of contacts
//api/GroupContact/354/
public ContactModel Get(int id) //get contact id #354
public void PostContact(ContactModel model) //add contact (overwrite if exits)
public void Delete(int id) //delete contact if exists
如果您希望您的 URL 显示为嵌套的(例如:/api/Group/Contacts
, /api/Group/Contact
),你可以看看我写的另一篇文章 https://stackoverflow.com/a/10471854/215068。恕我直言,asp.net 的路由需要调整以支持更容易的嵌套......但这是一个不同的问题;-)