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
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/071f73bb-e141-4a68-ae61-05635382934f
Mira este artículo: resolvió mi problema casi a la perfección. Tuve que cambiar su objeto [] Escriba a una cadena, pero solo estoy usando cadenas: cadena tipo Clave / pares de valores, por lo que no hay problemas allí.