serialize serializar newtonsoft leer jsonconvert deserialize deserializar c# wcf json dictionary serialization

c# - serializar - Problema de deserialización con DataContractJsonSerializer



serializar y deserializar json c# (2)

Tengo la siguiente pieza de JSON:

[{ "name": "numToRetrieve", "value": "3", "label": "Number of items to retrieve:", "items": { "1": "1", "3": "3", "5": "5" }, "rules": { "range": "1-2" } }, { "name": "showFoo", "value": "on", "label": "Show foo?" }, { "name": "title", "value": "Foo", "label": "Foo:" }]

Versión todo en una línea (adecuada para una cadena literal):

[{/"name/":/"numToRetrieve/",/"value/":/"3/",/"label/":/"Number of items to retrieve:/",/"items/":{/"1/":/"1/",/"3/":/"3/",/"5/":/"5/"},/"rules/":{/"range/":/"1-2/"}},{/"name/":/"showFoo/",/"value/":/"on/",/"label/":/"Show foo?/"},{/"name/":/"title/",/"value/":/"Foo/",/"label/":/"Foo:/"}]

En el ejemplo anterior, se requieren name , value y label , pero los items y las rules son opcionales.

Aquí está la clase en la que trato de deserializar:

using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; namespace foofoo { [DataContract] public sealed class FooDef { [DataMember(Name = "name", IsRequired = true)] public string Name { get; set; } [DataMember(Name = "value", IsRequired = true)] public string Value { get; set; } [DataMember(Name = "label", IsRequired = true)] public string Label { get; set; } [DataMember(Name = "items", IsRequired = false)] public Dictionary<string, string> Items { get; set; } [DataMember(Name = "rules", IsRequired = false)] public Dictionary<string, string> Rules { get; set; } } }

Aquí está el código que uso para deserializar:

var json = new DataContractJsonSerializer(typeof(List<FooDef>)); var bar = "[{/"name/":/"numToRetrieve/",/"value/":/"3/",/"label/":/"Number of items to retrieve:/",/"items/":{/"1/":/"1/",/"3/":/"3/",/"5/":/"5/"},/"rules/":{/"range/":/"1-2/"}},{/"name/":/"showFoo/",/"value/":/"on/",/"label/":/"Show foo?/"},{/"name/":/"title/",/"value/":/"Foo/",/"label/":/"Foo:/"}]"; var stream = new MemoryStream(Encoding.UTF8.GetBytes(bar)); var foo = json.ReadObject(stream); stream.Close();

Todo va razonablemente bien, excepto que los items y las rules están vacíos para el primer pase de FooDef . He intentado todo bajo el sol para tratar de que se llenen: clases personalizadas, NameValueCollection , KeyValuePair<string, string> , List de ambas últimas, y cualquier otra colección que parezca aplicarse. [EDIT: me olvidé de probar Hashtable , que parecía ser un candidato obvio. No funcionó.]

El problema, como yo lo veo, es que la pieza clave bajo los items y las rules es abierta. Es decir, no siempre se llamará range o 3 . ¿Algún consejo o idea?


En mi humilde opinión, no hay forma de deserializar la cadena JSON que proporcionó en una clase .NET utilizando DataContractJsonSerializer.

El problema proviene de la forma en que DataContractJsonSerializer serializa diccionarios. Podría usar un serializador alternativo como Json.NET (que recomiendo encarecidamente) o JavaScriptSerializer (creo que ya no está en uso en favor de DataContractJsonSerializer, pero funcionará para su escenario).

También puedes leer these rants .

Documentación: serialización de colecciones - Json.NET