目前推荐使用Web API进行部分更新的方式是什么?
我想知道如何用ASP.NET Web API的RESTful接口实现部分更新? 比方说,我们通过以下结构的线路传递对象:
public class Person { public int Id { get; set; } public string Username { get; set; } public string Email { get; set; } }
如何支持一次只更新一个Person
部分,例如Email
属性? build议通过OData和PATCH动词来实现,还是自行实现PATCH?
目前最新的Web API 稳定版本(从2012年8月起)不支持。 所以,如果你想使用的是Web API RTM,你将不得不自己实现整个pipe道。
这就是说,OData预发行包通过新的Delta<T>
对象支持部分更新。 目前Microsoft.AspNet.WebApi.OData包已经在RC版本(0.3),可以从这里获得: http : //www.nuget.org/packages/Microsoft.AspNet.WebApi.OData
一旦你安装了,你可以相应地使用它:
[AcceptVerbs("PATCH")] public void Patch(int id, Delta<Person> person) { var personFromDb = _personRepository.Get(id); person.Patch(personFromDb); _personRepository.Save(); }
你可以这样从客户端调用它:
$.ajax({ url: 'api/person/1', type: 'PATCH', data: JSON.stringify(obj), dataType: 'json', contentType: 'application/json', success: function(callback) { //handle errors, do stuff yada yada yada } });
这样做的一个明显的优点是它适用于任何属性,而且您不必关心是否更新Email
或Username
或者是什么。
您可能也想看看这个post,因为它显示了一个非常类似的技术http://techbrij.com/http-patch-request-asp-net-webapi
编辑(更多信息):为了只使用PATCH ,除了添加OData包之外,您不需要启用任何与OData相关的任何操作,即可访问Delta<TEntityType>
对象。
你可以这样做:
public class ValuesController : ApiController { private static List<Item> items = new List<Item> {new Item {Id = 1, Age = 1, Name = "Abc"}, new Item {Id = 2, Age = 10, Name = "Def"}, new Item {Id = 3, Age = 100, Name = "Ghj"}}; public Item Get(int id) { return items.Find(i => i.Id == id); } [AcceptVerbs("PATCH")] public void Patch(int id, Delta<Item> item) { var itemDb = items.Find(i => i.Id == id); item.Patch(itemDb); } }
如果你的产品是,让我们说:
{ "Id": 3, "Name": "hello", "Age": 100 }
您可以使用以下方式修补/api/values/3
:
{ "Name": "changed!" }
这将正确地更新您的对象。
Delta<TEntity>
会跟踪您的变化。 它是一个dynamic类,充当您的types的轻量级代理,并将理解原始对象(即从数据库)和客户端传递的差异。
这不会以任何方式影响其余的API(当然除了用更新的DLL来替代,以促进OData包依赖性)。
我已经添加了一个示例项目来演示PATCH + Delta的工作 – 你可以在这里获取它(VS.SV1212)