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();
}
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
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);
}
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();
}
}
}
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()
Oneliner utilisant Newtonsoft.Json.Linq
:
string prettyJson = JToken.Parse(uglyJsonString).ToString(Formatting.Indented);
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!
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.