2010-04-18 8 views
153

Ich benutze .NET JSON Parser und möchte meine Config-Datei so serialisieren, dass sie lesbar ist. Also statt:Wie bekomme ich JSON in .NET mit C# formatiert?

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

würde Ich mag etwas schöneres wie:

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

Mein Code so etwas wie dieses:

using System.Web.Script.Serialization; 

var ser = new JavaScriptSerializer(); 
configSz = ser.Serialize(config); 
using (var f = (TextWriter)File.CreateText(configFn)) 
{ 
    f.WriteLine(configSz); 
    f.Close(); 
} 

Antwort

177

Sie werden eine harte Zeit haben, dies zu erreichen mit JavaScriptSerializer

Versuchen Sie JSON.Net.

Mit geringfügigen Modifikationen von JSON.Net Beispiel

using System; 
using Newtonsoft.Json; 

namespace JsonPrettyPrint 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      Product product = new Product 
       { 
        Name = "Apple", 
        Expiry = new DateTime(2008, 12, 28), 
        Price = 3.99M, 
        Sizes = new[] { "Small", "Medium", "Large" } 
       }; 

      string json = JsonConvert.SerializeObject(product, Formatting.Indented); 
      Console.WriteLine(json); 

      Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json); 
     } 
    } 

    internal class Product 
    { 
     public String[] Sizes { get; set; } 
     public decimal Price { get; set; } 
     public DateTime Expiry { get; set; } 
     public string Name { get; set; } 
    } 
} 

Ergebnisse

{ 
    "Sizes": [ 
    "Small", 
    "Medium", 
    "Large" 
    ], 
    "Price": 3.99, 
    "Expiry": "\/Date(1230447600000-0700)\/", 
    "Name": "Apple" 
} 

Dokumentation: Serialize an Object

+0

Es gibt auch ein Beispiel für die Formatierung von Json-Ausgabe auf seinem Blog http://james.newtonking.com/archive/2008/ 10/16/asp-net-mvc-und-json-net.aspx – R0MANARMY

+13

@Brad Er zeigte absolut den gleichen Code, aber mit einem Modell – Mia

105

Eine kürzere Beispielcode für Json.Net Bibliothek

private static string FormatJson(string json) 
{ 
    dynamic parsedJson = JsonConvert.DeserializeObject(json); 
    return JsonConvert.SerializeObject(parsedJson, Formatting.Indented); 
} 
80

Wenn Sie einen JSON-String und wollen „prettify“, aber nicht wollen, es serialise und von einem bekannten C# geben Sie die folgende funktioniert der Trick (mit JSON.NET):

using System; 
using System.IO; 
using Newtonsoft.Json; 

class JsonUtil 
{ 
    public static string JsonPrettify(string json) 
    { 
     using (var stringReader = new StringReader(json)) 
     using (var stringWriter = new StringWriter()) 
     { 
      var jsonReader = new JsonTextReader(stringReader); 
      var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented }; 
      jsonWriter.WriteToken(jsonReader); 
      return stringWriter.ToString(); 
     } 
    } 
} 
+1

Für nur verschönern eine JSON-String ist dies eine sehr gute Lösung als die anderen ... –

+2

Die folgenden Anwendungsfälle schlagen fehl: 'JsonPrettify (" null ")' und 'JsonPrettify (" \ "string \" ")' – Ekevoo

+1

Danke @Ekevoo, ich habe es auf meine vorherige Version zurückgerollt! –

5

Sie folgende Standardmethode verwenden für Json

JsonReaderWriterFactory.CreateJsonWriter (Stream Stream, Encoding Codierung, bool ownsStream, bool Gedankenstrich, string indentChars) formatiert zu werden

Nur gesetzt "indent == true"

Probieren Sie etwas wie dieses

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()); 
     } 
    } 

Achten Sie auf Linien

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

Sie InvariantCulture verwenden sollten auf den Computern mit verschiedenen regionalen Einstellungen Ausnahme während der Deserialisierung zu vermeiden. Zum Beispiel, das ungültige Format doppelt oder DateTime manchmal verursachen sie.

Für Deserialisieren

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); 
     } 
    } 

Dank!

38

Kürzeste Version zu vorhandenen JSON verschönern: (bearbeiten: mit JSON.net)

JToken.Parse("mystring").ToString() 

Eingang:

{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }} 

Ausgang:

{ 
    "menu": { 
    "id": "file", 
    "value": "File", 
    "popup": { 
     "menuitem": [ 
     { 
      "value": "New", 
      "onclick": "CreateNewDoc()" 
     }, 
     { 
      "value": "Open", 
      "onclick": "OpenDoc()" 
     }, 
     { 
      "value": "Close", 
      "onclick": "CloseDoc()" 
     } 
     ] 
    } 
    } 
} 

Um ein Objekt pretty-Druck:

JToken.FromObject(myObject).ToString() 
+1

Dies funktioniert auch ohne vorher die Struktur des JSON zu kennen. Und es ist die kürzeste Antwort hier – foresightyj

+1

Dies funktioniert, aber nur, wenn das Json-Objekt kein Array ist. Wenn Sie wissen, dass es ein Array sein wird, könnten Sie stattdessen JArray.Parse verwenden. –

+3

Ah, guter Punkt, danke. Ich habe meine Antwort aktualisiert, um 'JToken' anstelle von' JObject' zu verwenden. Dies funktioniert mit Objekten oder Arrays, da 'JToken' die Vorfahrklasse für' JObject' und 'JArray' ist. – asherber

1

Zuerst habe ich hinzufügen wollte Kommentar unter Duncan Smart Post, aber leider habe ich noch nicht genug Reputation um Kommentare zu hinterlassen. Also werde ich es hier versuchen.

Ich möchte nur über Nebenwirkungen warnen.

JsonTextReader analysiert JSON intern in typisierte JTokens und serialisiert sie anschließend zurück.

Zum Beispiel, wenn Ihre ursprüngliche JSON war

{ "double":0.00002, "date":"\/Date(1198908717056)\/"} 

Nachdem Sie

erhalten Prettify
{ 
    "double":2E-05, 
    "date": "2007-12-29T06:11:57.056Z" 
} 

Natürlich beide JSON-String sind gleichwertig und werden deserialisieren strukturell gleich Objekte, aber wenn Sie erhalten müssen Original-String-Werte, müssen Sie dies in Betracht ziehen

Verwandte Themen