2012-04-25 21 views
8

Ho creato una semplice applicazione di elenco delle cose da fare in asp.net mvc 3 con web api e dbContext. (con backbone e requirejs per il client) Tutto funziona bene, ma sono un po 'infastidito dal fatto che devo inviare l'intero modello al server se controllo o deseleziono un oggetto come fatto. Vorrei solo inviare il campo "completato" quando si inviano dati.aggiornamento parziale con asp.net web api

Devo menzionare che sto anche utilizzando JsonNetFormatter per utilizzare JSON.NET come serializzatore predefinito (spiegato qui: http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx).

Attualmente questo è il mio metodo di controllo API per aggiornare il modello

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

Prende questo come dati JSON

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

Fuori rotta questo funziona, ma sta aggiornando l'intero modello, dovrebbe aggiorna solo 1 campo. Posso ottenere solo di inviare i campi modificati al server dal browser, ma non sono sicuro di come dovrebbe essere il metodo web API. Stavo pensando di fare qualcosa con FormCollection ma questo non sembra funzionare con la web api in quanto sembra che stia cercando di serializzare i valori dei moduli inviati direttamente al tipo FormCollection, ottengo questo errore.

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

Come posso inviare un aggiornamento parziale per 1 o più campi da un modello nel mio spazio web api? Voglio solo inviare i campi aggiornati al server, e da lì solo aggiornare quei campi al database. Certamente non voglio interrogare il database prima di aggiornarlo.

risposta

2

Un approccio potrebbe essere quello di utilizzare uno strumento chiamato Automapper e configurarlo in modo che i valori nulli non sovrascrivano quelli esistenti durante il mapping degli oggetti Todo. Per esempio:

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

Poi si sarebbe solo per mappare il valore dell'oggetto ricevuto a quello esistente, in questo modo:

Mapper.Map(todo, item); 

Un altro suggerimento sarebbe quello di utilizzare PATCH invece di PUT che è more appropriate to partial updates of resources according to REST.

+3

Non venduto su questo. Cosa succede se si desidera impostare un campo su null? –

+2

Non si è in grado di stabilire se il valore nullo è stato impostato dal mittente o è stato semplicemente impostato dal fatto che un campo è stato omesso. In questo caso, raccomanderei invece di usare il verbo PATCH. – elolos

-3

È necessario interrogare l'oggetto originale dal database, impostare le sue proprietà & chiamata _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); 
} 

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

+7

Questo non risponde alla domanda –