¿Cómo serializar Dictionary a través de WCF?

Tengo un contrato de datos con un miembro de datos escrito como Dictionary .

La referencia del servicio web generado expone esto como un miembro con el tipo ArrayOfKeyValueOfstringstringKeyValueOfstringstring[] .

¿Alguien ha visto esto antes?

WCF solo serializa la estructura , porque lo que termina en el cable debe ser lo suficientemente autocontenido para ser útil para cualquier cliente, no solo para los clientes .NET.

Algún cliente desarrollado en una plataforma diferente puede no compartir el concepto de un ‘diccionario’, por lo que sería demasiado restrictivo serializar un diccionario a una representación que conlleve un conocimiento implícito sobre la clase subyacente.

El cliente puede no estar orientado a objetos.

Un diccionario es más que una estructura ; también contiene un comportamiento (por ejemplo, cuando asigna una clave que ya existe, sobreescribe esa clave, etc.) y ese comportamiento no puede atravesar el cable.

En otras palabras, los diccionarios y muchos otros tipos de .NET no son interoperables, por lo que WCF no intentará conservarlos en un ServiceContract.

Probablemente sea mejor que diseñe un DataContract personalizado para sus datos.

Como WCF tiene que convertir todo a XML, tiene que caber como XML … Las colecciones generalmente se convierten en matrices.

Un diccionario es muy difícil de representar como xml, por eso tiene este tipo en el otro lado. Puede especificar que SvcUtil.exe use colecciones específicas en lugar de matrices en el código proxy generado, pero no estoy seguro de que funcione para un diccionario. Yo diría que debería evitar el uso de un Diccionario aquí y usar una Colección más simple.

Lo que haría sería crear mi propio tipo de datos, [DataContract], hacer que tenga dos campos de tipo Cadena, luego hacer una Colección de estos que llene con todo lo que encuentre en el Diccionario. Luego envió esa colección a través del cable, luego la convierte de nuevo en un diccionario en el otro lado.

Hay una manera de hacerlo … El contrato de operación es en realidad una cadena. Escapo de la cuerda de Json para mantenerla como una cuerda. Luego, en el método web, desapego la cadena y la analizo en un diccionario usando NewtonSoftJson. Utilicé el diccionario, pero también podría hacer el diccionario si quisiera. Espero que esto sea útil …

Usé la librería NewtonSoft Json …

código c #

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