2012-04-25 69 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