2009-10-02 11 views
20

Ich habe einen Datenvertrag mit einem Datenelement wie Dictionary<string, string> eingegeben.Wie man Dictionary <string, string> durch WCF serialisiert?

Die generierte Webdienst-Referenz macht dies als Element mit dem Typ ArrayOfKeyValueOfstringstringKeyValueOfstringstring[] verfügbar.

Hat jemand das schon mal gesehen?

+0

Möglicherweise möchten Sie auf dieser Seite einen Blick nehmen in die WCF-Dokumentation (die viel aktueller ist als diese Frage): https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts –

Antwort

23

WCF serialisiert nur Struktur, weil das, was auf dem Draht endet muß umluftunabhängigem genug sein, um nützlich zu sein für jeden Client, nicht nur .NET-Clients.

Einige Clients, die auf einer anderen Plattform entwickelt wurden, können das Konzept eines "Wörterbuchs" nicht teilen. Daher wäre es zu einschränkend, ein Dictionary zu einer Repräsentation zu serialisieren, die implizites Wissen über die zugrunde liegende Klasse enthält.

Der Client ist möglicherweise nicht einmal objektorientiert.

Ein Dictionary ist mehr als Struktur - es enthält auch Verhalten (z. B. wenn Sie einem bereits vorhandenen Schlüssel zuweisen, überschreiben Sie diesen Schlüssel usw.) und dieses Verhalten kann nicht über die Leitung übertragen werden.

Mit anderen Worten, Wörterbücher und viele andere .NET-Typen sind nicht interoperabel, daher wird WCF nicht versuchen, sie in einem ServiceContract beizubehalten.

Sie wären wahrscheinlich besser dran, einen benutzerdefinierten DataContract für Ihre Daten zu entwerfen.

+2

Das doesn Ich meine, der Client-Proxy kann nicht generiert werden wandeln Sie die Daten in ein Wörterbuch zurück.Was bewirkt die Option "Dictionary Collection Type" des Visual Studio-Dialogfelds "Configure Service Reference", wenn sie auf System.Collections.Generic.Dictionary festgelegt ist? – xr280xr

5

Da WCF alles in XML konvertieren muss, muss es als XML passen ... Sammlungen werden in der Regel in Arrays konvertiert.

Ein Wörterbuch ist preety schwer als xml darzustellen, deshalb haben Sie diesen Typ auf der anderen Seite. Sie können SvcUtil.exe angeben, um bestimmte Auflistungen anstelle von Arrays im generierten Proxy-Code zu verwenden, aber ich bin nicht sicher, ob es für ein Dictionary funktioniert. Ich würde sagen, dass Sie hier vermeiden sollten, ein Wörterbuch zu verwenden und eine einfachere Sammlung zu verwenden.

Was ich tun würde ist meinen eigenen Datentyp zu erstellen, [DataContract] es, machen Sie es zwei Felder vom Typ String, dann machen Sie eine Sammlung von diesen, die Sie mit allem, was Sie im Wörterbuch finden. Dann schickte ich diese Sammlung durch den Draht und wandelte sie dann in ein Wörterbuch auf der anderen Seite um.

+0

ist es nicht so etwas wie eine Sequenz von de dah? – kenny

+1

@Kenny: Nein, der Standard-DataContractSerializer unterstützt keine Attribute auf XML-Knoten (aus Leistungsgründen) –

+2

@kenny: ehrlich gesagt. Ja. und es gibt eine Menge Leute da draußen, die serialisierbare Wörterbücher geschrieben haben, die sehr natürliche Schlüssel und Wert-XML-Elemente verwenden. Ein Wörterbuch ist nur eine Liste von Paaren. das einzige gültige Argument ist das von Mark Seemann über das Verhalten. Aber ein Wörterbuch ist sicherlich nicht schwer in xml darzustellen. Auch Python serialisiert Wörterbücher gut und verwendet die gleiche Darstellung wie der Code selbst! mach einfach 'str (mydict)', um es zu bekommen. –

1

Es gibt einen Weg, es zu tun .. Der Betriebsvertrag ist eigentlich eine Zeichenfolge. Ich entkomme der JSON-Saite, um sie als Saite zu behalten. Ich dann in der Web-Methode entpacken Sie die Zeichenfolge und analysieren Sie es in ein Wörterbuch mit NewtonSoftJson Ich benutzte Wörterbuch, aber Sie könnten auch Wörterbuch tun, wenn Sie wollten. Hoffe, dass dies nützlich ...

I NewtonSoft Json-Bibliothek verwendet ...

C# -Code

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) { 
    }, 
}); 
Verwandte Themen