2013-02-06 18 views
6

Qual è il problema?Come utilizzare Delta <T> da OData Web API Microsoft ASP.NET con codice First JsonMediaTypeFormatter

Sto tentando di abilitare l'applicazione patch nella mia app API web ASP.net. Sto usando il primo framework di entità del codice.

devo metodo la seguente intestazione, che è possibile impostare un punto di interruzione e sarà colpito:

[AcceptVerbs("PATCH")] 
public async Task<HttpResponseMessage> Patch(long appId, long id, Delta<SimpleFormGroup> formGroup) 

Tuttavia quando chiamo formGroup.Patch (entità), non vengono apportate modifiche al mio entità. Se metto il seguente nella finestra immediata:

formGroup.GetChangedPropertyNames() 

Quindi questa raccolta è vuota, che sembra errata.

Cosa ho provato?

ho riferisco ai seguenti esempi

http://techbrij.com/http-patch-request-asp-net-webapi http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta/

Sembra essere un problema con il JSON MediaType Formatter non saper costruire correttamente l'oggetto Delta, però nel 2 ° collegamento filip sembra suggerire che dovrebbe funzionare senza oDataMediaTypeFormatter.

Ho iniziato la linea di tentativo di serializzare il mio modello in rappresentazione EDMX, quindi da lì estrarre il CSDL in modo da poter creare un oDataMediaTypeFormatter, ma ho anche riscontrato un intoppo, inoltre sembra un po 'eccessivo.

Se qualcuno potesse far luce su questo sarebbe molto apprezzato. Fammi sapere se sono necessarie ulteriori informazioni.

EDIT:

Ecco la definizione di classe per SimpleFormGroup:

public class SimpleFormGroup 
{ 
    public int LastUpdate; 

    public string Identifier; 

    public string Title; 

    public int DisplayOrder; 
} 

Ed ecco i dati che io mando:

Content-Type: 'application/json' 

{ "DisplayOrder" : "20 } 

Grazie, Pete

+0

È possibile aggiungere la definizione di classe per SimpleFormGroup e JSON che si sta inviando nella richiesta di PATCH? –

+0

Vedi sopra ... In questo momento ho trovato una soluzione alternativa, ma sarei interessato anche a sentire i tuoi pensieri –

+0

Questo non è valido JSON, considerando la citazione a sinistra del 20. C'è una citazione di chiusura in giro il valore o nessuna quotazione di apertura? – Rich

risposta

8

Interessante, sembra Delta<T> con membri int non funziona in JSON.

Sfortunatamente, Delta<T> è stato creato appositamente per OData. Se Delta<T> sembra funzionare con qualsiasi formattatore diverso da OData, è una coincidenza piuttosto che essere intenzionale.

La buona notizia però è che non c'è nulla che ti impedisca di definire il tuo PATCH formato per JSON, e sarei sorpreso se nessuno ne avesse già scritto uno che funzioni meglio con Json.NET. È possibile che rivedremo le patch in una versione futura dell'API Web e proveremo a creare una storia coerente che funzioni su tutti i programmi di formattazione.

+3

con un Delta supportabile per l'uso non solo da OData ma dall'API Web in generale sarebbe estremamente vantaggioso. mi rattrista ogni volta che creo un'azione Patch() che si basa sulla conoscenza discreta del mittente per eseguire un aggiornamento parziale :(c'è un problema su codeplex che possiamo votare per aiutare a legittimare la necessità? –

+3

Questo è un buon posto per inizio: http://aspnetwebstack.codeplex.com/workitem/777. –

+3

Ho notato che soffoca su * int * e * Guid * per JSON. Ho postato una soluzione qui http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta /. In breve, JSON.NET considera int long e Guid come stringa, quindi il codice Delta deve proteggerlo, –

4

Grazie a Youssef per indagare e scoprire perché le cose non funzionavano. Spero che questo possa essere risolto lungo la linea.

Sono riuscito a risolverlo da solo alla fine dopo aver esaminato la fonte del pacchetto oData. Ho scelto di implementare un altro MediaTypeFormatter che avvolge la logica in quanto fornisce un facile accesso a HttpContent, ma ci sono altri modi per raggiungere questo obiettivo.

La parte fondamentale è stato capire come interpretare il primo modello di codice, vedere la linea commentata di seguito:

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) 
{ 
    var builder = new ODataConventionModelBuilder(); 

    // This line will allow you to interpret all the metadata from your code first model 
    builder.EntitySet<EfContext>("EfContext"); 

    var model = builder.GetEdmModel(); 
    var odataFormatters = ODataMediaTypeFormatters.Create(model); 
    var delta = content.ReadAsAsync(type, odataFormatters).Result; 

    var tcs = new TaskCompletionSource<object>(); 
    tcs.SetResult(delta); 
    return tcs.Task; 
} 

Spero che questo consente di risparmiare qualcuno qualche problema!

Problemi correlati