|
|
Ligne 18 : |
Ligne 18 : |
| </kode> | | </kode> |
|
| |
|
| = JsonSerializer = | | = [https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/how-to JsonSerializer] = |
| | {{info | Replacement of {{boxx|Newtonsoft.Json}}}} |
| <kode lang='cs'> | | <kode lang='cs'> |
| var jsonSerializerOptions = new JsonSerializerOptions | | var jsonSerializerOptions = new JsonSerializerOptions |
Version du 4 avril 2024 à 11:54
Liens
Contexte
|
class MaClasse
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
|
|
{
"Property1": "Value1",
"Property2": "Value2"
}
|
|
Replacement of Newtonsoft.Json |
|
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter() }
};
var json = JsonSerializer.Serialize(myObject, jsonSerializerOptions);
var myObject = JsonSerializer.Deserialize<MyClass>(json, jsonSerializerOptions);
|
|
Pas de pretty print |
|
using System.Web.Script.Serialization; // System.Web.Extensions.dll
var mc = new MaClasse() { Property1 = "Value1", Property2 = "Value2" };
// sérialisation
string json = new JavaScriptSerializer().Serialize(mc);
// désérialisation
MaClasse mc2 = new JavaScriptSerializer().Deserialize<MaClasse>(json);
|
|
Newtonsoft.Json est disponible via NuGet. |
|
using Newtonsoft.Json;
// lecture du fichier
var jsonContent = File.ReadAllText("/chemin/vers/le/fichier.json");
// Désérialiser
MaClasse monObjet = JsonConvert.DeserializeObject<MaClasse>(text);
// sérialiser avec pretty print
var json = JsonConvert.SerializeObject(monObjet, Formatting.Indented);
class MaClasse
{
// Forcer cette propriété en deuxième position
[JsonProperty(Order = 2)]
public string P1 { get; set; }
// Forcer cette propriété en première position
[JsonProperty(Order = 1)]
public string P2 { get; set; }
// Ne pas sérialiser cette propriété
[JsonIgnore]
public string P3 { get; set; }
// Ne pas sérialiser cette propriété si sa valeur est nulle
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string P31 { get; set; }
public IList<string> P32 { get; private set; } = new List<string>();
// Ne pas sérialiser cette propriété si la liste est vide
public bool ShouldSerializeP32()
{
return P32.Count > 0;
}
// mapping de la propriété avec odata.p4 en sérialisation et désérialisation
[JsonProperty(PropertyName = "odata.p4")]
public string P4 { get; set; }
|
|
L'ordre par défaut est de -1 |
JsonSerializerSettings
|
// Affiche les types .NET dans le json généré
var jsonSerializerSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };
JsonConvert.SerializeObject(data, Formatting.Indented, jsonSerializerSettings);
|
|
{
"$type": "System.Collections.Generic.List`1[[MonNamespace.MaClasse, MonAssembly]], mscorlib",
"$values": [
{
"$type": "MonNamespace.MaClasse, MonAssembly",
"MaPropriété": "valeur"
}
]
}
|
JObject
JObject |
collection de JProperties
|
JProperties |
contient un Name string et une Value JToken
|
JToken |
valeur JSON générique: string, JArray, JObject, JProperty
|
|
{
"prop1": "value1",
"prop2": "2.34",
"prop3": [
{
"sousprop1": "value11",
"sousprop2": "11.34"
},
{
"sousprop1": "value12",
"sousprop2": "12.34"
}
]
}
|
|
JObject jo = JObject.Parse(json);
string jsonText = jo.ToString();
// dynamic
dynamic d = JObject.Parse(json);
d.prop2; // 2.34
// Parse et ToObject
JArray jArray = JArray.Parse(json);
List<MyClass> myObjects = jArray.ToObject<List<MyClass>>();
// path
string value11 = jo.SelectToken("prop3[0].sousprop1").Value<string>(); // value11
string value11 = (string)jo.SelectToken("prop3[0].sousprop1"); // cast au lieu du Value<T>()
// élément du tableau prop3 correspondant au filtre (JObject)
JToken token = jo.SelectToken("$.prop3[?(@.sousprop1 == 'value12')]");
// élément du tableau prop3 correspondant au filtre (JObject)
JToken token = jo.SelectToken("$.prop3[?(@.sousprop2 > 12)]");
// JSONException si plusieurs éléments correspondent au filtre
// éléments du tableau prop3 correspondant au filtre (JObject)
IEnumerable<JToken> tokens = jo.SelectTokens("$.prop3[?(@.sousprop2 > 11)]");
// toutes les sousprop2 filles de prop3
IEnumerable<JToken> tokens = jo.SelectTokens("$.prop3[?(@.sousprop2)].sousprop2");
JToken token = jo.SelectToken("$.prop3[?(@.sousprop1 == 'value12')].sousprop2"); // 12.34
token.Replace("13");
foreach (JProperty property in jo.Properties())
{
string name = property.Name; // prop1
JToken valueToken = property.Value;
if (valueToken.Type == JTokenType.String)
{
string valueString = valueToken.Value<string>(); // value1
}
else if (valueToken.Type == JTokenType.Array)
{
JArray valueArray = valueToken.Value<JArray>();
foreach (JObject sousJo in valueArray.Children<JObject>())
{
foreach (JProperty sousProperty in sousJo.Properties())
{
string sousName = sousProperty.Name; // sousprop1
JToken sousValueToken = sousProperty.Value;
if (sousValueToken.Type == JTokenType.String)
{
string sousValueString = sousValueToken.Value<string>(); // value11
}
}
}
}
}
|
Permet de modifier le comportement de sérialisation.
|
[JsonConverter(typeof(MyListJsonConverter))]
public class MyList
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
}
public class MyListJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var myList = (MyList) value;
serializer.Serialize(writer, new int[] { myList.Prop1, myList.Prop2 });
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var ml = new MyList();
if (reader.TokenType != JsonToken.Null)
{
if (reader.TokenType == JsonToken.StartArray)
{
JToken token = JToken.Load(reader);
var values = token.ToObject<List<int>>();
ml.Prop1 = values[0];
ml.Prop2 = values[1];
}
}
return ml;
}
public override bool CanConvert(Type objectType)
{
return typeof(MyList).IsAssignableFrom(objectType);
}
}
|
|
// sérialisation custom
[
[ 1, 11 ],
[ 2, 22 ]
]
// sérialisation par défaut
[
{ "Prop1": 1, "Prop2": 11 },
{ "Prop1": 2, "Prop2": 22 },
]
|
On souhaite désérialiser dans une classe abstraite, mais le mécanisme de désérialisation ne peut créer cette classe abstraite.
Il faut donc surcharger la méthode ReadJson du JsonConverter pour lui permettre de choisir quelle classe concrète doit être utilisée.
|
public abstract class A
{
public abstract string P1 { get; set; }
}
public class B : A
{
public override string P1 { ... }
}
public class C : A
{
public override string P1 { ... }
}
public class AJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(A).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject item = JObject.Load(reader);
if (item["P1"].Value<string>() == "...")
{
return item.ToObject<B>();
}
else
{
return item.ToObject<C>();
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
var monObjet = JsonConvert.DeserializeObject<A>(jsonText, new AJsonConverter());
|
Fichier JSON
|
// écriture des items dans jsonFilePath
File.WriteAllText(jsonFilePath, JsonConvert.SerializeObject(items, Formatting.Indented));
// lecture de jsonFilePath dans items
using (StreamReader file = File.OpenText(jsonFilePath))
{
var serializer = new JsonSerializer();
items = (List<Item>)serializer.Deserialize(file, typeof(List<Item>));
}
|
|
The library is built-in as part of the .NET Core 3.0 shared framework. |
|
Doesn't serialize Dictionary is key is not a string. |