2012-04-25 56 views
8

我用asp api和dbContext在asp.net mvc 3中创建了一个简单的待办事项列表应用程序。 (与骨干和客户端requirejs) 一切工作正常,但我有点困扰的事实,我必须将整个模型发送到服务器,如果我检查或取消选中待办事项完成。 我只想在提交数据时发送“完成”字段。用asp.net web api部分更新

我应该提到,我还使用JsonNetFormatter来使用JSON.NET作为默认串行器(在这里解释:http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx)。

目前,这是我的API控制的方法来更新模型

public HttpResponseMessage Put(Todo todo) 
{ 
    _db.Entry(todo).State = EntityState.Modified; 
    _db.SaveChanges(); 
    return new HttpResponseMessage(HttpStatusCode.NoContent); 
} 

它以此为JSON数据

{"content":"Pick up milk","done":false,"id":10} 

当然,这工作,但它是更新整个模型,它应该只更新1个字段。 我可以实现只从浏览器发送更改的字段到服务器,但我不知道什么Web API方法应该看起来像。 我正在考虑用FormCollection做些什么,但是这似乎并不适用于web api,因为它似乎试图将提交的formvalues直接序列化为FormCollection类型,我得到这个错误。

Cannot deserialize JSON object (i.e. {"name":"value"}) into type 'System.Web.Mvc.FormCollection'. 

如何从模型发送一个或多个字段的部分更新到我的web api? 我只想将更新的字段发送到服务器,并从那里只将这些字段更新到数据库。我当然不希望在更新之前查询数据库。

回答

2

一种方法是使用一种称为工具Automapper并对其进行配置,以便在映射Todo对象时空值不会覆盖现有值。例如:

Mapper.CreateMap<Todo,Todo>() 
     .ForMember(d => d.Id, o => o.Ignore()) 
     .ForAllMembers(mo => mo.Condition(cond => !cond.IsSourceValueNull)); 

那么你就只需要接收的对象值映射到现有的,像这样:

Mapper.Map(todo, item); 

另一个建议是使用,而不是PUT这是more appropriate to partial updates of resources according to REST补丁。

+3

没有出售。如果您想将字段设置为空,该怎么办? – 2013-11-18 22:50:41

+2

您将无法判断发件人是设置了空值还是仅仅通过忽略字段来设置空值。在这种情况下,我会建议使用PATCH动词。 – elolos 2013-11-19 11:44:27

-3

您需要查询从数据库中原来的对象,设置其属性&调用_db.SaveChange()

public HttpResponseMessage Put(Todo todo){ 
var item = _db.Todo.First(i => i.id = todo.id); 
item.Content = todo.Content; 
item.Done = todo.Done; 
_db.SaveChanges(); 
return new HttpResponseMessage<Todo>(HttpStatusCode.Accepted); 
} 

参考:http://msdn.microsoft.com/en-us/library/dd456854.aspx

+7

这并不回答问题 – 2012-08-06 15:13:47