2011-02-01 59 views
48

¿Es posible serializar un .Net Dictionary < Key, Value > en JSON con DataContractJsonSerializer que es del formato:C# JSON Serialización del diccionario en {key: value, ...} en lugar de {key: key, value: value, ...}

{ 
    key0:value0, 
    key1:value1, 
    ... 
} 

I utilizar el diccionario < K, V >, porque no hay estructura predefinida de las entradas.

Estoy interesado sólo por DataContractJsonSerializer resultado! Ya encontré un ejemplo "Surrogate", pero hay un "dato" adicional en la salida, y si el diccionario < K, String > es, el escape también es falso.


¡He encontrado la solución, qué necesidad! En primer lugar, un "diccionario" serializable clase: (Por supuesto, esta muestra funciona de una manera, pero necesita dont't deserialización)

[Serializable] 
public class MyJsonDictionary<K, V> : ISerializable { 
    Dictionary<K, V> dict = new Dictionary<K, V>(); 

    public MyJsonDictionary() { } 

    protected MyJsonDictionary(SerializationInfo info, StreamingContext context) { 
     throw new NotImplementedException(); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) { 
     foreach(K key in dict.Keys) { 
      info.AddValue(key.ToString(), dict[ key ]); 
     } 
    } 

    public void Add(K key, V value) { 
     dict.Add(key, value); 
    } 

    public V this[ K index ] { 
     set { dict[ index ] = value; } 
     get { return dict[ index ]; } 
    } 
} 

Uso:

public class MainClass { 
    public static String Serialize(Object data) { 
     var serializer = new DataContractJsonSerializer(data.GetType()); 
     var ms = new MemoryStream(); 
     serializer.WriteObject(ms, data); 

     return Encoding.UTF8.GetString(ms.ToArray()); 
    } 

    public static void Main() { 
     MyJsonDictionary<String, Object> result = new MyJsonDictionary<String, Object>(); 
     result["foo"] = "bar"; 
     result["Name"] = "John Doe"; 
     result["Age"] = 32; 
     MyJsonDictionary<String, Object> address = new MyJsonDictionary<String, Object>(); 
     result["Address"] = address; 
     address["Street"] = "30 Rockefeller Plaza"; 
     address["City"] = "New York City"; 
     address["State"] = "NY"; 

     Console.WriteLine(Serialize(result)); 

     Console.ReadLine(); 
    } 
} 

Y el resultado:

{ 
     "foo":"bar", 
     "Name":"John Doe", 
     "Age":32, 
     "Address":{ 
     "__type":"MyJsonDictionaryOfstringanyType:#Json_Dictionary_Test", 
     "Street":"30 Rockefeller Plaza", 
     "City":"New York City", 
     "State":"NY" 
     } 
    } 
+7

¿Alguna razón específica que desea limitar a 'DataContractJsonSerializer'? Cada vez que hago una comparación (que es varias veces: estoy muy "interesado" en mis serializadores) esta es la herramienta JSON menos preferida para .NET; Siempre miro JavaScriptSerializer o JSON.Net –

+0

¿En qué contexto estás usando esto? Es decir, es una aplicación WCF, una aplicación ASP.NET u otra cosa. ¿Está utilizando el DataContractJsonSerilizer de forma tal que está llamando al WriteObject usted mismo o está haciendo algo de framework para usted? –

+0

Lo que no está claro en su publicación es que desea que 1 objeto JSON con propiedades (y sus valores) sean los pares nombre/valor en el diccionario. O eso o algo está mal, ya que no puede ser una matriz JSON ya que no se puede tener una matriz JSON donde cada elemento de la matriz tenga diferentes nombres de propiedad. Entonces, ¿puedes tener claro el formato real que estás buscando obtener? –

Respuesta

4

estoy usando fuera de la MVC4 caja con el código (tenga en cuenta los dos parámetros dentro ToDictionary)

var result = new JsonResult() 
{ 
    Data = new 
    { 
     partials = GetPartials(data.Partials).ToDictionary(x => x.Key, y=> y.Value) 
    } 
}; 

consigo lo que se espera:

{"partials":{"cartSummary":"\u003cb\u003eCART SUMMARY\u003c/b\u003e"}} 

Importante: WebAPI en MVC4 utiliza serialización JSON.NET lista para usar, pero el resultado de acción de web estándar JsonResult no lo hace. Por lo tanto, recomiendo usar un ActionResult personalizado para forzar la serialización de JSON.NET. También puede obtener buen formato

He aquí una sencilla ActionResult JsonNetResult

http://james.newtonking.com/archive/2008/10/16/asp-net-mvc-and-json-net.aspx

Verás la diferencia (y puede asegurarse de que está utilizando el correcto) al serializar una fecha:

Microsoft manera:

{"wireTime":"\/Date(1355627201572)\/"} 

JSON.NET manera:

{"wireTime":"2012-12-15T19:07:03.5247384-08:00"} 
35

Json.NET hace esto ...

Dictionary<string, string> values = new Dictionary<string, string>(); 
values.Add("key1", "value1"); 
values.Add("key2", "value2"); 

string json = JsonConvert.SerializeObject(values); 
// { 
// "key1": "value1", 
// "key2": "value2" 
// } 

Más ejemplos: Serializing Collections with Json.NET

+0

La segunda línea debe ser 'string values ​​= JsonConvert.SerializeObject (values);' –

11

uso de propiedad UseSimpleDictionaryFormat en DataContractJsonSerializer y ponerlo a true.

Hace el trabajo :)

+0

¿cómo se puede establecer esa configuración para el comportamiento predeterminado de wcf al serializar la respuesta http? – Vinhent

+0

¡Trabajó para mí, gracias! Tuve que usar 'config.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;' en 'WebApiConfig.cs'. – SharpC

+0

¡Te amo por este hombre de respuesta! ¡Me salvó! <3 – Jules

Cuestiones relacionadas