命名空间System.Text.Json
JsonSerializerOptions 类
序列化选项用于控制要对象的序列化的或这Json 字符的反序列化,
构造函数
内容来源:如何使用 System.Text.Json 实例化 JsonSerializerOptions 实例
JsonSerializerOptions() :初始化JsonSerializerOptions类的一个新实例。
JsonSerializerOptions(JsonSerializerDefaults) :用由指定的JsonSerializerDefaults确定的预定义选项集构造一个新的枚举 JsonSerializerOptions实例。
JsonSerializerOptions(JsonSerializerOptions) :将选项从JsonSerializerOptions实例复制到一个新实例。
构造函数的使用
1、重用JsonSerializerOptions实例
如果你使用相同的选项重复使用JsonSerializerOptions,不要每次使用时都创建一个新的JsonSerializerOptions实例。为每个调用重用相同的实例。此指导适用于为自定义转换器编写的代码和调用JsonSerializer时。序列化或JsonSerializer.Deserialize。跨多个线程使用相同的实例是安全的。选项实例上的元数据缓存是线程安全的,并且该实例在第一次序列化或反序列化之后是不可变的。
下面的代码演示了使用新选项实例的性能损失。
JsonSerializerOptions(JsonSerializerDefaults)案例如下:


using System.Diagnostics;
using System.Text.Json;
namespace OptionsPerfDemo
{
public record Forecast(DateTime Date, int TemperatureC, string Summary);
public class Program
{
public static void Main()
{
Forecast forecast = new(DateTime.Now, 40, "Hot");
JsonSerializerOptions options = new() { WriteIndented = true };
int iterations = 100000;
var watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
Serialize(forecast, options);
}
watch.Stop();
Console.WriteLine($"Elapsed time using one options instance: {watch.ElapsedMilliseconds}");
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
Serialize(forecast);
}
watch.Stop();
Console.WriteLine($"Elapsed time creating new options instances: {watch.ElapsedMilliseconds}");
}
private static void Serialize(Forecast forecast, JsonSerializerOptions? options = null)
{
_ = JsonSerializer.Serialize<Forecast>(
forecast,
options ?? new JsonSerializerOptions() { WriteIndented = true });
}
}
}
// Produces output like the following example:
//
//Elapsed time using one options instance: 190
//Elapsed time creating new options instances: 40140View Code
2、JsonSerializerOptions的Web默认值为JsonSerializerDefaults.Web
JsonSerializerDefaults.Web枚举项目包含以下:
- PropertyNameCaseInsensitive =
true - JsonNamingPolicy = CamelCase
- NumberHandling = AllowReadingFromString
有一个JsonSerializerOptions构造函数,它允许您用ASP的默认选项创建一个新实例。NET Core用于web应用程序,如下例所示:


using System.Text.Json;
namespace OptionsDefaults
{
public class Forecast
{
public DateTime? Date { get; init; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
};
public class Program
{
public static void Main()
{
Forecast forecast = new()
{
Date = DateTime.Now,
TemperatureC = 40,
Summary = "Hot"
};
JsonSerializerOptions options = new(JsonSerializerDefaults.Web)
{
WriteIndented = true
};
Console.WriteLine(
$"PropertyNameCaseInsensitive: {options.PropertyNameCaseInsensitive}");
Console.WriteLine(
$"JsonNamingPolicy: {options.PropertyNamingPolicy}");
Console.WriteLine(
$"NumberHandling: {options.NumberHandling}");
string forecastJson = JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine($"Output JSON:\n{forecastJson}");
Forecast? forecastDeserialized =
JsonSerializer.Deserialize<Forecast>(forecastJson, options);
Console.WriteLine($"Date: {forecastDeserialized?.Date}");
Console.WriteLine($"TemperatureC: {forecastDeserialized?.TemperatureC}");
Console.WriteLine($"Summary: {forecastDeserialized?.Summary}");
}
}
}
// Produces output like the following example:
//
//PropertyNameCaseInsensitive: True
//JsonNamingPolicy: System.Text.Json.JsonCamelCaseNamingPolicy
//NumberHandling: AllowReadingFromString
//Output JSON:
//{
// "date": "2020-10-21T15:40:06.9040831-07:00",
// "temperatureC": 40,
// "summary": "Hot"
//}
//Date: 10 / 21 / 2020 3:40:06 PM
//TemperatureC: 40
//Summary: HotView Code
3、复制JsonSerializerOptions
JsonSerializerOptions(JsonSerializerOptions) :将选项从JsonSerializerOptions实例复制到一个新实例。案例如下:


using System.Text.Json;
namespace CopyOptions
{
public class Forecast
{
public DateTime Date { get; init; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
};
public class Program
{
public static void Main()
{
Forecast forecast = new()
{
Date = DateTime.Now,
TemperatureC = 40,
Summary = "Hot"
};
JsonSerializerOptions options = new()
{
WriteIndented = true
};
JsonSerializerOptions optionsCopy = new(options);
string forecastJson =
JsonSerializer.Serialize<Forecast>(forecast, optionsCopy);
Console.WriteLine($"Output JSON:\n{forecastJson}");
}
}
}
// Produces output like the following example:
//
//Output JSON:
//{
// "Date": "2020-10-21T15:40:06.8998502-07:00",
// "TemperatureC": 40,
// "Summary": "Hot"
//}View Code
属性:
记忆方法:4个Hand(枚举处理、数组处理) 、3个Ignore、Json属性命名策略 3(属性名命名规则、字典key做Json属性命名规则、师傅) 其他。
- AllowTrailingCommas
- Converters
- DefaultBufferSize 默认缓冲区大小 获取或设置创建临时缓冲区时要使用的默认缓冲区大小(以字节为单位)。
- DefaultIgnoreCondition
- DictionaryKeyPolicy
- Encoder 编码器 获取或设置转义字符串时要使用的编码器,或为空以使用默认编码器。
- IgnoreNullValues 忽略 NullValues 过时了。获取或设置一个值,该值指示在序列化和反序列化期间是否忽略空值。缺省值为false。
- IgnoreReadOnlyFields
- IgnoreReadOnlyProperties
- IncludeFields 是否序列化字段 获取或设置一个值,该值指示是否在序列化和反序列化期间处理字段。缺省值为false, 设置位true后,就可以序列化属性和字段。。
- MaxDepth
- NumberHandling
- PropertyNameCaseInsensitive
- PropertyNamingPolicy
- ReadCommentHandling 阅读注释处理 获取或设置一个值,该值定义在反序列化期间如何处理注释, 用到
JsonCommentHandling枚举。 - ReferenceHandler
- UnknownTypeHandling 未知类型处理 获取或设置一个对象,该对象指定在反序列化期间如何处理声明为object的类型的反序列化。
- WriteIndented
2、Converters :【C# 序列化】 自定义Json转换器模式
详细请查看:
4、忽略所有默认值属性/或字段
设置该属性,需要JsonIgnoreCondition枚举。若要防止对值类型属性中的默认值进行序列化,请将 DefaultIgnoreCondition 属性设置为JsonIgnoreCondition.WhenWritingDefault,如以下示例中所示:
相当于
[JsonIgnore(Condition =JsonIgnoreCondition.WhenWritingDefault)]
public string Name3 = default;//将被忽略,因为使用默认值MySerializeable serializeable = new ();
var serializeOption = new JsonSerializerOptions()
{
AllowTrailingCommas=false,
WriteIndented=true,
DefaultIgnoreCondition=JsonIgnoreCondition.WhenWritingDefault,//忽略默认的属性或字段
IncludeFields=true,//开启忽略字段,默认情况下是false
};
string jsonString = JsonSerializer.Serialize(serializeable,serializeOption);
writer.WriteLine(jsonString);
writer.Close();
public class MySerializeable
{
public int Name4 ;//会被忽略因为是默认值
}5、字典Key序列化的命名规则
如果要序列化的对象的属性为 Dictionary<string,TValue> 类型,则 string 键可转换为 camel 大小写。 为此,请将 DictionaryKeyPolicy 设置为 JsonNamingPolicy.CamelCase,如下面的示例中所示:
MySerializeable serializeable = new() ;
serializeable.Lictionaryy.Add("XiaoMi","26");
serializeable.Lictionaryy.Add("LuaWei", "26");
var serializeOption = new JsonSerializerOptions()
{
WriteIndented = true,
DictionaryKeyPolicy =JsonNamingPolicy.CamelCase,
};
string jsonString = JsonSerializer.Serialize<MySerializeable>(serializeable,serializeOption);
var desr=JsonSerializer.Deserialize<MySerializeable>(jsonString,serializeOption);//反序列化时候要使用序列化配置
Console.WriteLine(jsonString);
Console.Read();
public class MySerializeable
{
public double FloatNumberOne { get; set; }
public int NumberTwo { get; set; }
public Dictionary<string,string> Lictionaryy { get; set; }=new Dictionary<string,string>();
}
/*{
"FloatNumberOne": "NaN",
"NumberTwo": 123,
"Lictionaryy": {
"xiaoMi": "26",
"luaWei": "26"
}
}*/6、Encoder
//保证中文字符正确显示。CjkUnifiedIdeographs 象行文字 代表中文(Chinese)、日文(Japanese )、韩文(Korean)的字符集合
JsonSerializerOptions jso = new JsonSerializerOptions
{ Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs),//从拉丁文字到象行文字
};
public class Myserliazer
{
[JsonInclude]
public string Name = "哈哈"
}
8条和9条 IgnoreReadOnlyFields和IgnoreReadOnlyProperties
忽略大小
StreamWriter writer = GetCurrentStream();
MySerializeable serializeable = new ();
var serializeOption = new JsonSerializerOptions()
{
AllowTrailingCommas=false,
WriteIndented=true,
IgnoreReadOnlyFields=true, //忽略只读字段
IgnoreReadOnlyProperties=false, //默认false
};
string jsonString = JsonSerializer.Serialize(serializeable,serializeOption);
writer.WriteLine(jsonString);
writer.Close();
StreamWriter GetCurrentStream()
{
Environment.CurrentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fullName = Directory.CreateDirectory("Test").FullName;
StreamWriter streamWriter = File.CreateText(Path.Combine(fullName, "text.txt"));
return streamWriter;
}
public class MySerializeable
{
public readonly string Name = "dfdf";
public readonly int[] Info= { 10, 20, 30 };
public string Description { private set; get; }
}
/*输出
* {
"Description": null,
"Info": [
10,
20,
30
]
}*/
10条和18条IncludeFields和WriteIndented
StreamWriter writer = GetCurrentStream();
MySerializeable serializeable = new ();
var serializeOption = new JsonSerializerOptions()
{
AllowTrailingCommas=false,
IncludeFields = true,//包含字段,默认只包含属性,设置位true后,就可以序列化属性和字段。
WriteIndented=true,//格式化输出
};
string jsonString = JsonSerializer.Serialize(serializeable,serializeOption);
writer.WriteLine(jsonString);
writer.Close();
StreamWriter GetCurrentStream()
{
Environment.CurrentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fullName = Directory.CreateDirectory("Test").FullName;
StreamWriter streamWriter = File.CreateText(Path.Combine(fullName, "text.txt"));
return streamWriter;
}
public class MySerializeable
{
public string Name = "dfdf";
public int[] Info= { 10, 20, 30 };
}
/*输出
* {
"Name": "dfdf",
"Info": [
10,
20,
30
]
}*/11、MaxDepth
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using GongHuiNewtonsoft.Json;
using GongHuiNewtonsoft.Json.Serialization;
using GongHuiNewtonsoft.Json.Converters;
namespace JSONDemo
{
class Program
{
static void Main(string[] args)
{
try
{
JsonConvert.DeserializeObject<List<IList<IList<string>>>>(@"[
[
[
'3',
'Three',
'III'
]
]
]", new JsonSerializerSettings
{
MaxDepth = 2
//MaxDepth=3
});
}
catch (JsonReaderException ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
12、序列化/反序列化数字解析方式
在设置JsonNumberHandling选项时用到JsonSerializerDefaults 位枚举
序列化和反序列化时数字的保存和解析方法
【AllowNamedFloatingPointLiterals 模式】不是标准的json格式,“NaN”、“Infinity”和“-Infinity”字符串标记可以被读为浮点常量,这些常量的Single和Double值将被写为它们对应的JSON字符串表示。
【Strict 反序列化模式】数字将只从数字标记读取,将只被写入JSON数字("Number":123,)。
【AllowReadingFromString 反序列化模式】可以从String令牌中读取数字。不阻止从Number令牌读取数字。Number":"123"
【WriteAsString 序列化模式】不是标准的json格式,序列化时将数字写成字符串的形式。
使用案例:
MySerializeable serializeable = new() ;
serializeable.FloatNumberOne = double.NaN;//序列化时候,需要将 NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,否会出错
serializeable.NumberTwo = 123;
var serializeOption = new JsonSerializerOptions()
{
WriteIndented = true,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals|
JsonNumberHandling.AllowReadingFromString|
JsonNumberHandling.WriteAsString,
};
string jsonString = JsonSerializer.Serialize<MySerializeable>(serializeable,serializeOption);
var desr=JsonSerializer.Deserialize<MySerializeable>(jsonString,serializeOption);//反序列化时候要使用序列化配置,不配置会报错
Console.WriteLine(jsonString);
public class MySerializeable
{
public double FloatNumberOne { get; set; }
public int NumberTwo { get; set; }
}
13、反序列化时不区分属性大小写
默认情况下,反序列化会查找 JSON 与目标对象属性之间区分大小写的属性名称匹配。 若要更改该行为,请将 JsonSerializerOptions.PropertyNameCaseInsensitive 设置为 true:
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
/*{
"date": "2019-08-01T00:00:00-07:00",
"temperatureCelsius": 25,
"summary": "Hot",
}
*/
14、PropertyNamingPolicy 命名规则
该选项用到JsonNamingPolicy 类,可以继承该类重写ConvertName()方法自定义命名规则
MySerializeable serializeable = new() ;
serializeable.FloatNumberOne = double.NaN;//序列化时候,需要将 NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
serializeable.NumberTwo = 123;
var serializeOption = new JsonSerializerOptions()
{
WriteIndented = true,
NumberHandling=JsonNumberHandling.AllowNamedFloatingPointLiterals,
PropertyNamingPolicy =JsonNamingPolicy.CamelCase,
};
string jsonString = JsonSerializer.Serialize<MySerializeable>(serializeable,serializeOption);
var desr=JsonSerializer.Deserialize<MySerializeable>(jsonString,serializeOption);//反序列化时候要使用序列化配置
Console.WriteLine(jsonString);
Console.Read();
public class MySerializeable
{
public double FloatNumberOne { get; set; }
public int NumberTwo { get; set; }
}
/*{
"floatNumberOne": "NaN",
"numberTwo": 123
}*/自定义命名规则。


MySerializeable serializeable = new() ;
serializeable.FloatNumberOne = double.NaN;//序列化时候,需要将 NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
serializeable.NumberTwo = 123;
var serializeOption = new JsonSerializerOptions()
{
WriteIndented = true,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
PropertyNamingPolicy = new ToUpper(),
};
string jsonString = JsonSerializer.Serialize<MySerializeable>(serializeable,serializeOption);
var desr=JsonSerializer.Deserialize<MySerializeable>(jsonString,serializeOption);//反序列化时候要使用序列化配置
Console.WriteLine(jsonString);
Console.Read();
public class ToUpper : JsonNamingPolicy
{
public override string ConvertName(string name) => name.ToUpper();
}
public class MySerializeable
{
public double FloatNumberOne { get; set; }
public int NumberTwo { get; set; }
}
/*{
"FLOATNUMBERONE": "NaN",
"NUMBERTWO": 123
}*/View Code
15、允许注释
默认情况下,JSON 中不允许使用注释和尾随逗号。 若要在 JSON 中允许注释,请将 JsonSerializerOptions.ReadCommentHandling 属性设置为 JsonCommentHandling.Skip。
var options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true,
};
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options)!;下面是包含注释和尾随逗号的示例 JSON:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25, // Fahrenheit 77
"Summary": "Hot", /* Zharko */
// Comments on
/* separate lines */
}
IJsonOnDeserializing, IJsonOnDeserialized, IJsonOnSerializing, IJsonOnSerialized
public class Serializeables : IJsonOnDeserializing, IJsonOnDeserialized,IJsonOnSerializing, IJsonOnSerialized
{
public bool[] Serbool = { true, true, true };
public void OnSerializing() => Console.WriteLine("序列化中");
public void OnDeserializing() => Console.WriteLine("反序列化中");
public void OnDeserialized() => Console.WriteLine("反序列化后");
public void OnSerialized() => Console.WriteLine("序列化后");
}
特性
编程是个人爱好
















