2013-02-06 1 views
6

Was ist das Problem?Verwendung von Delta <T> von Microsoft ASP.NET-Web-API OData mit Code First JsonMediaTypeFormatter

Ich versuche, das Patchen in meiner ASP.net Web API App zu aktivieren. Ich verwende Code First Entity Framework.

Ich habe die folgende Methode Header, die ich in einen Haltepunkt festgelegt und es wird getroffen:

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

Allerdings, wenn ich formGroup.Patch (juristische Person) nennen, sind meiner Einheit keine Änderungen vorgenommen. Wenn ich folgendes in das unmittelbare Fenster setze:

formGroup.GetChangedPropertyNames() 

Dann ist diese Sammlung leer, was falsch scheint.

Was habe ich versucht?

I bezogen habe auf die folgenden Beispiele

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

Es scheint ein Problem mit dem Json Media Formatter nicht zu wissen, wie das Delta-Objekt korrekt in der zweiten Verbindung, jedoch zu bauen filip scheint darauf hinzuweisen, dass es ohne oDataMediaTypeFormatter funktionieren sollte.

Ich habe angefangen, mein Modell zu EDMX-Darstellung zu serialisieren, dann von dort die CSDL extrahieren, so dass ich einen oDataMediaTypeFormatter erstellen kann, aber ich habe auch dort einen Haken gefunden, und es scheint ein bisschen übertrieben.

Wenn jemand Licht darauf werfen könnte, wäre es sehr geschätzt. Lassen Sie mich wissen, wenn weitere Informationen benötigt werden.

EDIT:

Hier ist die Klassendefinition für SimpleFormGroup:

public class SimpleFormGroup 
{ 
    public int LastUpdate; 

    public string Identifier; 

    public string Title; 

    public int DisplayOrder; 
} 

Und hier ist die Daten, die ich zu senden bin:

Content-Type: 'application/json' 

{ "DisplayOrder" : "20 } 

Danke, Pete

+0

Können Sie die Klassendefinition für SimpleFormGroup und den JSON, den Sie in der Anfrage an PATCH senden, hinzufügen? –

+0

Siehe oben ... Ich habe im Moment tatsächlich einen Workaround dafür gefunden, aber ich würde gerne Ihre Gedanken hören. –

+0

Das ist kein gültiger JSON, wenn man das Zitat links von den 20 berücksichtigt. Gibt es ein Schlusszitat herum der Wert oder kein Öffnungszitat? – Rich

Antwort

8

Interessant, es sieht wieausmit int-Mitgliedern funktioniert nicht in JSON.

Leider wurde Delta<T> speziell für OData erstellt. Wenn Delta<T> mit einem anderen Formatierungsprogramm als OData zu arbeiten scheint, ist es eher Zufall als Absicht.

Die gute Nachricht ist jedoch, dass es nichts hält, das Sie davon abhält, Ihr eigenes PATCH-Format für JSON zu definieren, und ich würde mich wundern, wenn niemand bereits einen geschrieben hat, der besser mit Json.NET funktioniert. Es ist möglich, dass wir das Patchen in einer zukünftigen Version der Web-API noch einmal überprüfen und versuchen, eine konsistente Story zu entwickeln, die über Formatierer hinweg funktioniert.

+3

mit einem unterstützbaren Delta für die Verwendung nicht nur von OData, sondern von Web-API im Allgemeinen sehr gut mit JSON.NET würde extrem sein vorteilhaft. Es macht mich jedes Mal traurig, wenn ich eine Patch() -Aktion erstelle, die auf dem diskreten Wissen des Übermittlers beruht, um ein teilweises Update durchzuführen :(Gibt es ein Problem bei Codeplex, über das wir abstimmen können, um die Notwendigkeit zu legitimieren? –

+3

Dies ist ein guter Ort Start: http://aspnetwebstack.codeplex.com/workitem/777. –

+3

Ich bemerkte, dass es an * int * und * Guid * für JSON erstickt.Ich habe hier einen Workaround http://www.strathweb.com/2013/01 veröffentlicht/Kurz: JSON.NET würde Int so lange und Guid als String behandeln, so dass der Code dagegen schützen muss, –

4

Danke an Youssef für die Untersuchung und Entdeckung, warum die Dinge nicht funktionierten. Hoffentlich kann das auf der ganzen Linie gelöst werden.

Ich schaffte es, am Ende selbst zu knacken, nachdem ich über die oData-Paketquelle geforscht hatte. Ich entschied mich, einen anderen MediaTypeFormatter zu implementieren, der die Logik umschließt, da sie einfachen Zugriff auf HttpContent bietet, aber es gibt andere Möglichkeiten, dies zu erreichen.

Der wichtigste Teil aus war herauszufinden, wie der Code erste Modell zu interpretieren, finden Sie in der kommentierten Zeile unter:

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; 
} 

Hope this jemand etwas Mühe spart!