2013-02-06 13 views
6

Na czym polega problem?Jak korzystać z Delta <T> z Microsoft ASP.NET Web API OData z kodem First JsonMediaTypeFormatter

Próbuję włączyć łatanie w mojej api aplikacji ASP.net web. Używam frameworka kodu pierwszego elementu.

mam metoda następujący nagłówek, który można ustawić punkt przerwania i to będzie hit:

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

Jednakże gdy zgłoszę formGroup.Patch (podmiot), są dokonywane żadne zmiany do mojej jednostki. Jeśli umieściłem następujące okno w bezpośrednim oknie:

formGroup.GetChangedPropertyNames() 

Ta kolekcja jest pusta, co wydaje się błędne.

Co próbowałem?

I zostały w odniesieniu do następujących przykładów

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

Wydaje się, że problem z JSON MediaType Formatter nie wiedząc, jak zbudować obiekt Delta prawidłowo, jednak w 2 linku filip wydaje się sugerować, że powinien działać bez oDataMediaTypeFormatter.

Zacząłem od próby serializowania mojego modelu do reprezentacji EDMX, a następnie wyciągnąłem z niego plik CSDL, dzięki czemu mogę utworzyć oDataMediaTypeFormatter, ale też tam trafiłem i wydaje się to trochę przesadzone.

Jeśli ktokolwiek mógłby rzucić jakiekolwiek światło na ten temat, byłoby to bardzo cenne. Daj mi znać, jeśli potrzebujesz więcej informacji.

EDIT:

Oto definicja klasy dla SimpleFormGroup:

public class SimpleFormGroup 
{ 
    public int LastUpdate; 

    public string Identifier; 

    public string Title; 

    public int DisplayOrder; 
} 

A oto dane, które przesyłam:

Content-Type: 'application/json' 

{ "DisplayOrder" : "20 } 

Dzięki, Pete

+0

Czy możesz dodać definicję klasy dla SimpleFormGroup i JSON, który wysyłasz, do PATCH? –

+0

Zobacz powyżej ... W tej chwili znalazłem obejście tego problemu, ale chciałbym również usłyszeć twoje przemyślenia. –

+0

To nie jest poprawne JSON, biorąc pod uwagę cytat po lewej stronie 20. Czy jest tam końcowy cytat? wartość lub brak cytatu z otwarcia? – Rich

Odpowiedz

8

Interesujące, wygląda na Delta<T> z członkami int nie działa w JSON.

Niestety, Delta<T> został stworzony specjalnie dla OData. Jeśli wydaje się, że Delta<T> pracuje z dowolnym formaterem innym niż OData, jest to raczej zbieg okoliczności niż celowe.

Dobrą wiadomością jest jednak to, że nic nie powstrzyma cię od zdefiniowania własnego formatu PATCH dla JSON-a, i byłbym zaskoczony, gdyby nikt nie napisał tego, który działa lepiej z Json.NET. Możliwe, że zajmiemy się ponownym łataniem w przyszłym wydaniu Web API i spróbujemy wymyślić spójną historię, która działa na wszystkich formaterach.

+3

z obsługą Delta do użytku nie tylko z OData, ale z interfejsu Web API w ogóle byłaby wyjątkowo korzystny. to mnie zasmuca za każdym razem, gdy tworzę akcję Patch(), która polega na dyskretnej wiedzy autora, aby wykonać częściową aktualizację :(czy jest problem z kodeksem, na którym możemy głosować, aby pomóc zasymulować potrzebę? –

+3

To jest dobre miejsce na start: http://aspnetwebstack.codeplex.com/workitem/777. –

+3

Zauważyłem, że dławi się na * int * i * Guid * dla JSON.Zostałem opublikować obejście tutaj http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta /. Krótko mówiąc, JSON.NET potraktował int jako długi, a Guid jako string, więc kod Delta musi się przed nim chronić, –

4

Dzięki Youssefowi za zbadanie i odkrycie, dlaczego rzeczy nie działały. Mam nadzieję, że uda się rozwiązać problem.

Udało mi się to samemu złamać po przejrzeniu źródła pakietu oData. Wybrałem implementację kolejnej MediaTypeFormatter, która owija logikę, ponieważ zapewnia łatwy dostęp do tio HttpContent, ale istnieją inne sposoby, aby to osiągnąć.

Kluczowym elementem było dowiedzieć się, jak interpretować kod pierwszego modelu, patrz skomentowany linię poniżej:

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

Nadzieja Oszczędza to ktoś jakieś kłopoty!

Powiązane problemy