2009-10-02 9 views
20

Mam umowę danych z członkiem danych wpisanym jako Dictionary<string, string>.Jak serializować słownik <ciąg, ciąg> przez WCF?

Wygenerowany odniesienia serwis internetowy naraża to jako członek z typem ArrayOfKeyValueOfstringstringKeyValueOfstringstring[].

Czy ktoś to widział wcześniej?

+0

Możesz spojrzeć na tę stronę w dokumentacja WCF (która jest znacznie nowsza niż to pytanie): https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts –

Odpowiedz

23

WCF serializes tylko strukturę, ponieważ to, co kończy się na przewodzie musi być samowystarczalny wystarczy być użyteczne dla dowolny klienta, a nie tylko .NET klientów.

Niektórzy klienci opracowani na innej platformie mogą nie dzielić się pojęciem "słownika", więc byłoby zbyt ograniczające, aby serializować słownik do reprezentacji, która przenosi niejawną wiedzę na temat podstawowej klasy.

Klient może nawet nie być zorientowany obiektowo.

Słownik ma więcej niż strukturę - zawiera również zachowanie (np. Przypisanie do klucza, który już istnieje, zastąpienie tego klawisza itp.) I zachowanie to nie może przejść przez przewód.

Innymi słowy, słowniki i wiele innych typów .NET nie są interoperacyjne, tak WCF nie będzie próbował zachować je w ServiceContract.

Pewnie można lepiej projektowania niestandardowych DataContract do swoich danych.

+2

To doesn Oznacza to, że nie można wygenerować proxy klienta przekonwertuj dane z powrotem na słownik.Co robi opcja Visual Studio "Konfiguruj odniesienie do usługi" w oknie dialogowym "Typ zbioru słowników" po wybraniu opcji System.Collections.Generic.Dictionary? – xr280xr

5

Jak WCF musi konwertować wszystko na XML, to musi pasować jako XML ... Kolekcje są zazwyczaj zamieniane na tablicach.

A Dictionary jest prety trudno reprezentować jako xml, to dlaczego masz tego typu na drugiej stronie. Możesz określić SvcUtil.exe, aby używał określonych kolekcji zamiast tablic w wygenerowanym kodzie proxy, ale nie jestem pewien, czy będzie działał dla Słownika. Powiedziałbym, że powinieneś unikać używania Słownika i korzystać z prostszej Kolekcji.

Co mogę zrobić, to utworzyć własny typ danych, [DataContract] go, sprawić, że będą miały dwa pola typu String, a następnie utworzyć kolekcję tych, które wypełnisz wszystko, co znajdziesz w słowniku. Następnie wysłałeś tę kolekcję za pomocą drutu, a następnie przekonwertuj ją z powrotem na słownik po drugiej stronie.

+0

czy to nie jest po prostu coś w rodzaju de dah? – kenny

+1

@Keny: nie, standardowy obiekt DataContractSerializer nie obsługuje atrybutów na węzłach XML (ze względów wydajnościowych) –

+2

@kenny: szczerze. tak. i jest wielu ludzi, którzy pisali serializowalne słowniki, używając bardzo naturalnych kluczowych i wartościowych elementów xml. słownik to tylko lista par. jedynym słusznym argumentem jest ten z Mark Seemann o zachowaniu. Ale słownik z pewnością nie jest trudny do przedstawienia w xml. Również python serializuje słowników, używając tej samej reprezentacji co sam kod! po prostu wykonaj 'str (mydict)', aby go uzyskać. –

1

Istnieje sposób, aby to zrobić. Kontrakt operacyjny jest w rzeczywistości ciągiem. Unikałem ciągu jsonów, aby zachować ciąg. Następnie w metodzie internetowej usunięto łańcuch znaków i przeanalizowałem go w słowniku używając NewtonSoftJson Użyłem słownika, ale możesz też zrobić słownik, jeśli chcesz. Nadzieję, że to przydatne ...

użyłem NewtonSoft JSON biblioteki ...

C# kod

using Newtonsoft.Json; 
[OperationContract] 
    [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, 
     RequestFormat = WebMessageFormat.Json)] 
    public void testMethod(string jsonData) 
    { 
     string data = Uri.UnescapeDataString(jsonData); 
     Dictionary<string, string> x = jsonConvert.DeserializeObject<Dictionary<string, string>>(data); 
     foreach (KeyValuePair<string, string> kvp in x) 
     { 

     } 
    } 

JSCode

var Data = { 
    width: 400, 
    height: 200, 
    someString: "somedata" 
}; 

$.ajax({ 
    type: "POST", 
    url: "Service1.svc/testMethod", 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    timeout: 1000000,    
    data: '{"jsonData": "' + escape(JSON.stringify(Data)) + '"}', 
    error: function(error) { 
    }, 
    success: function (data) { 
    }, 
}); 
Powiązane problemy