在 C# 中,Newtonsoft.Json
的 JsonSerializerSettings
类提供了高度可定制的 JSON 序列化和反序列化选项。通过这个类,你可以设置诸如格式化、日期处理、引用处理、空值处理等配置,以满足特定需求。下面是 JsonSerializerSettings
的详细使用教程。
1. 基本使用
JsonSerializerSettings
主要用于配置 JsonConvert.SerializeObject
和 JsonConvert.DeserializeObject
方法。你可以创建一个 JsonSerializerSettings
对象,然后传递给这些方法。
using Newtonsoft.Json;
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented, // 控制缩进和格式化
NullValueHandling = NullValueHandling.Ignore // 忽略空值
};
var json = JsonConvert.SerializeObject(obj, settings);
2. 常见的 JsonSerializerSettings
属性
2.1. Formatting
控制 JSON 字符串的格式化方式。它可以是以下两个选项之一:
None
(默认值):不进行格式化,生成紧凑的 JSON 字符串。Indented
:对生成的 JSON 字符串进行缩进和换行处理,便于人类阅读。
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(obj, settings);
Console.WriteLine(json); // 输出的JSON将是格式化的
2.2. NullValueHandling
控制序列化过程中是否包含空值。选项:
Include
(默认值):序列化时包含空值。Ignore
:序列化时忽略空值。
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
string json = JsonConvert.SerializeObject(obj, settings);
2.3. DefaultValueHandling
控制是否序列化默认值。选项:
Include
(默认值):序列化时包含默认值。Ignore
:序列化时忽略默认值。
例如,如果对象属性的默认值为 0
或 false
,使用此设置可以选择是否包含这些值:
var settings = new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
};
string json = JsonConvert.SerializeObject(obj, settings);
2.4. DateFormatHandling
和 DateFormatString
用于控制日期序列化的格式。选项:
IsoDateFormat
(默认值):使用 ISO 8601 日期格式。MicrosoftDateFormat
:使用\/Date(ticks)\/
格式(微软风格)。
你也可以指定自定义的日期格式字符串:
var settings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.IsoDateFormat,
DateFormatString = "yyyy-MM-dd" // 自定义日期格式
};
string json = JsonConvert.SerializeObject(DateTime.Now, settings);
2.5. ReferenceLoopHandling
当对象之间存在引用循环时,控制如何处理。选项:
Error
(默认值):遇到循环引用时抛出异常。Ignore
:忽略循环引用。Serialize
:序列化循环引用。
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(obj, settings);
2.6. PreserveReferencesHandling
用于处理对象引用的方式。它会保留对象的引用,以确保在反序列化时正确恢复引用关系。选项:
None
(默认值):不保留引用。Objects
:仅保留对象引用。Arrays
:仅保留数组引用。All
:保留所有引用。
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
string json = JsonConvert.SerializeObject(obj, settings);
2.7. TypeNameHandling
序列化时添加 .NET
类型信息,用于反序列化时确定对象的真实类型。选项:
None
(默认值):不包含类型信息。Objects
:仅为对象添加类型信息。Arrays
:仅为数组添加类型信息。All
:为所有对象和数组添加类型信息。Auto
:只为需要的地方添加类型信息。
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
};
string json = JsonConvert.SerializeObject(obj, settings);
2.8. ContractResolver
用于定义序列化或反序列化过程中如何处理属性。例如,CamelCasePropertyNamesContractResolver
可以将属性名从 PascalCase
转换为 camelCase
。
var settings = new JsonSerializerSettings
{
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
};
string json = JsonConvert.SerializeObject(obj, settings);
2.9. Converters
自定义转换器可以用于处理特殊类型或自定义对象。你可以通过设置 Converters
来添加自定义的 JSON 转换器。
例如,自定义 bool
类型转换为 “Yes”/“No” 格式:
public class BoolToYesNoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(bool);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue((bool)value ? "Yes" : "No");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return (string)reader.Value == "Yes";
}
}
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new BoolToYesNoConverter() }
};
string json = JsonConvert.SerializeObject(true, settings); // 输出 "Yes"
3. 反序列化时使用 JsonSerializerSettings
JsonSerializerSettings
也可以用于反序列化时的设置。例如,使用 NullValueHandling
来忽略空值。
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
MyClass obj = JsonConvert.DeserializeObject<MyClass>(json, settings);
4. 使用 JsonSerializer
除了直接使用 JsonConvert
方法,你还可以通过 JsonSerializer
进行更高级的序列化和反序列化操作。JsonSerializer
提供了更灵活的 API,可以直接使用 JsonSerializerSettings
来控制序列化行为。
var serializer = JsonSerializer.Create(settings);
using (StreamWriter sw = new StreamWriter("output.json"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, obj);
}
5. 示例:完整的序列化和反序列化
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
class Program
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsStudent { get; set; }
}
static void Main(string[] args)
{
var person = new Person { Name = "Alvin", Age = 30, IsStudent = false };
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
// 序列化
string json = JsonConvert.SerializeObject(person, settings);
Console.WriteLine("Serialized JSON:");
Console.WriteLine(json);
// 反序列化
var deserializedPerson = JsonConvert.DeserializeObject<Person>(json, settings);
Console.WriteLine($"Deserialized Person: {deserializedPerson.Name}, {deserializedPerson.Age}, {deserializedPerson.IsStudent}");
}
}
输出:
{
"name": "Alvin",
"age": 30
}
总结
JsonSerializerSettings
是一个高度可配置的类,可以帮助你控制序列化和反序列化的行为。- 你可以通过设置
Formatting
,NullValueHandling
,ReferenceLoopHandling
,DateFormatHandling
等属性来自定义 JSON 输出和输入。 - 通过
ContractResolver
可以控制属性名的格式,例如将 PascalCase 转换为 camelCase。 - 你可以使用自定义转换器 (
Converters
) 来处理特殊的序列化需求。