2015-10-27 1 views
4

Fondamentalement une dupe de this question avec une différence notable - je dois utiliser DataContractJsonSerializer.DataContractJsonSerializer lisible par l'homme json

A

simples
using (var stream = new MemoryStream()) 
{ 
    var serializer = new DataContractJsonSerializer(typeof(Person)); 
    serializer.WriteObject(stream, obj); 
    ... 
    return stream.ToArray(); 
} 

seule ligne produit json, par exemple, (Lors de l'enregistrement dans le fichier)

...{"blah":"v", "blah2":"v2"}... 

Quelles sont les options pour le rendre

... 
{ 
    "blah":"v", 
    "blah2":"v2" 
} 
... 

je peux penser post-traitement ... Y at-il une option plus facile? Par exemple. similaire à la mise en forme xml produced by DataContractSerializer?

using (var stream = new MemoryStream()) 
{ 
    var serializer = new DataContractJsonSerializer(typeof(T)); 
    // "beautify" 
    using (var writer = new SomeKindOfWriter(stream)) 
     serializer.WriteObject(writer, obj); 
    ... 
    return stream.ToArray(); 
} 

est-il un moyen de faire une telle SomeKindOfWriter Embellir JSON en cas de besoin?

+0

Je ne suis pas sûr que vous pouvez le faire avec 'DataContractJsonSerializer' sans une fonction/bibliothèque externe pour le faire. – DavidG

+0

Eh bien, je peux faire un post-traitement en ce moment, mais cela semble stupide: analyser json en arrière (d'une certaine manière). Je serais heureux avec réponse où il y a quelque chose entre le flux de mémoire et json obtenant des valeurs et être capable de les formater. Semblable à ['XmlWriter'] (http://stackoverflow.com/a/739169/1997232) si cela est possible. – Sinatr

+0

Es-tu obligé d'utiliser exactement DataContractJsonSerializer? Peut-il s'agir d'une autre classe dérivée de XmlObjectSerializer? –

Répondre

0

https://stackoverflow.com/a/38538454/6627992

Vous pouvez utiliser suivant méthode standard pour obtenir au format JSON

JsonReaderWriterFactory.CreateJsonWriter (stream Stream, le codage de codage, bool ownsStream, tiret bool, indentChars string)

seulement mis "indent == true"

Essayez quelque chose comme

public readonly DataContractJsonSerializerSettings Settings = 
      new DataContractJsonSerializerSettings 
      { UseSimpleDictionaryFormat = true }; 

    public void Keep<TValue>(TValue item, string path) 
    { 
     try 
     { 
      using (var stream = File.Open(path, FileMode.Create)) 
      { 
       var currentCulture = Thread.CurrentThread.CurrentCulture; 
       Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; 

       try 
       { 
        using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
         stream, Encoding.UTF8, true, true, " ")) 
        { 
         var serializer = new DataContractJsonSerializer(type, Settings); 
         serializer.WriteObject(writer, item); 
         writer.Flush(); 
        } 
       } 
       catch (Exception exception) 
       { 
        Debug.WriteLine(exception.ToString()); 
       } 
       finally 
       { 
        Thread.CurrentThread.CurrentCulture = currentCulture; 
       } 
      } 
     } 
     catch (Exception exception) 
     { 
      Debug.WriteLine(exception.ToString()); 
     } 
    } 

Payez votre attention sur les lignes

var currentCulture = Thread.CurrentThread.CurrentCulture; 
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; 
    .... 
    Thread.CurrentThread.CurrentCulture = currentCulture; 

Vous devez utiliser InvariantCulture pour éviter exception lors de la désérialisation sur les ordinateurs avec différents paramètres régionaux. Par exemple, le format non valide de double ou DateTime les cause parfois.

Pour désérialisation

public TValue Revive<TValue>(string path, params object[] constructorArgs) 
    { 
     try 
     { 
      using (var stream = File.OpenRead(path)) 
      { 
       var currentCulture = Thread.CurrentThread.CurrentCulture; 
       Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; 

       try 
       { 
        var serializer = new DataContractJsonSerializer(type, Settings); 
        var item = (TValue) serializer.ReadObject(stream); 
        if (Equals(item, null)) throw new Exception(); 
        return item; 
       } 
       catch (Exception exception) 
       { 
        Debug.WriteLine(exception.ToString()); 
        return (TValue) Activator.CreateInstance(type, constructorArgs); 
       } 
       finally 
       { 
        Thread.CurrentThread.CurrentCulture = currentCulture; 
       } 
      } 
     } 
     catch 
     { 
      return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs); 
     } 
    } 

Merci!