web-dev-qa-db-fra.com

Comment obtenir un JSON formaté en .NET en utilisant C #?

J'utilise un analyseur JSON .NET et souhaite sérialiser mon fichier de configuration afin qu'il soit lisible. Donc au lieu de:

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

Je voudrais quelque chose de plus agréable comme:

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

Mon code ressemble à ceci:

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

Vous allez avoir du mal à accomplir cela avec JavaScriptSerializer.

Essayez JSON.Net .

Avec des modifications mineures de l'exemple JSON.Net

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

Résultats

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

Documentation: Sérialiser un objet

231
Sky Sanders

Un exemple de code plus court pour la bibliothèque Json.Net

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

Si vous avez une chaîne JSON et que vous souhaitez la "prettifier", mais que vous ne voulez pas la sérialiser vers et depuis un type C # connu, procédez comme suit (avec 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();
        }
    }
}
116
Duncan Smart

Version la plus courte pour embellir le JSON existant: (éditer: en utilisant JSON.net)

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

Contribution:

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

Sortie:

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

Pour imprimer un objet en beauté:

JToken.FromObject(myObject).ToString()
76
asherber

Oneliner utilisant Newtonsoft.Json.Linq:

string prettyJson = JToken.Parse(uglyJsonString).ToString(Formatting.Indented);
31
Dariusz

Vous pouvez utiliser la méthode standard suivante pour obtenir un Json formaté

JsonReaderWriterFactory.CreateJsonWriter (flux de flux, codage d'encodage, bool ownsStream, indentation de bool, string indentChars)

Ne définir que "indent == true"

Essayez quelque chose comme ça

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

Faites attention aux lignes

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

Vous devez utiliser InvariantCulture pour éviter les exceptions lors de la désérialisation sur les ordinateurs dotés de paramètres régionaux différents. Par exemple, un format non valide double ou DateTime peut parfois en provoquer.

Pour désérialiser

    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!

11
Makeman

Tout d'abord, je voulais ajouter un commentaire sous Duncan Smart post, mais malheureusement, je n'ai pas encore assez de réputation pour laisser des commentaires. Je vais donc l'essayer ici.

Je veux juste prévenir des effets secondaires.

JsonTextReader analyse en interne Json en JTokens dactylographié, puis les sérialise.

Par exemple, si votre JSON d'origine était

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

Après avoir fait plaisir, vous obtenez

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

Bien sûr, les deux chaînes json sont équivalentes et vont se désérialiser en objets structurellement égaux, mais si vous devez conserver les valeurs de chaîne d'origine, vous devez en tenir compte.

2
Max Venediktov