System.Text.Json
命名空间提供用于序列化和反序列化 JavaScript 对象表示法 (JSON) 的功能。
该库是作为 .NET Core 3.0 及更高版本共享框架的一部分内置的。
对于早期版本的框架,请安装 System.Text.Json NuGet 包。 包支持以下框架:
序列化行为:
public class Foo
{
public byte Member1 { get; set; }
public UInt16 Member2 { get; set; }
public UInt32 Member3 { get; set; }
public bool Member4 { get; set; }
public UInt32[] Member5 { get; set; }
}
static void Main(string[] args)
{
Foo foo = new Foo
{
Member1 = 0x11,
Member2 = 0x22,
Member3 = 0x33,
Member4 = true,
Member5 = new UInt32[] { 0x44, 0x55, 0x66 },
};
string json = System.Text.Json.JsonSerializer.Serialize(foo);
Console.WriteLine(json);//{"Member1":17,"Member2":34,"Member3":51,"Member4":true,"Member5":[68,85,102]}
File.WriteAllText(@"test.json", json);
Foo f = JsonSerializer.Deserialize<Foo>(json);
}
那就需要使用到JsonSerializerOptions类型的对象。
Type | Property | 说明 |
---|---|---|
bool | AllowTrailingCommas | 反序列化时是否允许末尾有多余的逗号,默认为法false,所以如果json字符串默认有多余的逗号还需要反序列化们就可以将此属性设置为true。 |
bool | WriteIndented | 该值定义Json是否应使用整齐打印。默认情况下为法false。 |
bool | PropertyNameCaseInsensitive | 反序列化的时候不区分大小写,默认为false。 |
JsonNamingPolicy | PropertyNamingPolicy | 设置为 JsonNamingPolicy.CamelCase 的时候,所有JSON属性名称使用camel大小写。 |
bool | IgnoreReadOnlyProperties | 忽略只读属性,默认值为false |
bool | IgnoreNullValues | 忽略值为Null的属性,默认值为false |
JsonCommentHandling | ReadCommentHandling | 反序列化时候怎么处理注释。默认为Disallow,允许注释的时候可以设置为Skip。 |
值得一提的是,用的什么JsonSerializerOptions序列化的就需要使用对应的JsonSerializerOptions反序列化,不需要另外转换啥的。
public class Foo
{
public byte Member1 { get; set; }
[JsonPropertyName("M2")]
public UInt16 Member2 { get; set; }
public UInt32 Member3 { get; set; }
public bool Member4 { get; set; }
public UInt32[] Member5 { get; set; }
}
在属性上定义JsonPropertyName特性,此特性设置的属性名称:
static void Main(string[] args)
{
Foo foo = new Foo
{
Member1 = 0x11,
Member2 = 0x22,
Member3 = 0x33,
Member4 = true,
Member5 = new UInt32[] { 0x44, 0x55, 0x66 },
};
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true,
};
string json = System.Text.Json.JsonSerializer.Serialize<Foo>(foo, options);
Console.WriteLine(json);
File.WriteAllText(@"test.json", json);
string j = File.ReadAllText(@"test.json");
Foo f = JsonSerializer.Deserialize<Foo>(j,options);
}
output:
{
"Member1": 17,
"M2": 34,
"Member3": 51,
"Member4": true,
"Member5": [
68,
85,
102
]
}
将上述代码的JsonSerializerOptions对象修改为:
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy=JsonNamingPolicy.CamelCase,
};
output:
{
"member1": 17,
"M2": 34,
"member3": 51,
"member4": true,
"member5": [
68,
85,
102
]
}
因为JsonPropertyName特性的优先级高于属性命名策略,所以还是“M2”。
还是设置PropertyNamingPolicy的值,不过这个值不在使用预定义好的CamelCase,需要我们自己定义一个。
public class UpperCaseNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name) =>
name.ToUpper();
}
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = new UpperCaseNamingPolicy(),
};
output:
{
"MEMBER1": 17,
"M2": 34,
"MEMBER3": 51,
"MEMBER4": true,
"MEMBER5": [
68,
85,
102
]
}
比如需要将枚举类型的整形值序列化为字符串名称,则可以使用系统预定义好的JsonStringEnumConverter。
添加一个枚举类型:
public enum TestEnum
{
EnumA=0,
EnumB,
EnumC
}
public class Foo
{
public byte Member1 { get; set; }
[JsonPropertyName("M2")]
public UInt16 Member2 { get; set; }
public UInt32 Member3 { get; set; }
public bool Member4 { get; set; }
public UInt32[] Member5 { get; set; }
public TestEnum Member6 { get; set; }
}
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true,
Converters = { new JsonStringEnumConverter()},
};
output:
{
"Member1": 17,
"M2": 34,
"Member3": 51,
"Member4": true,
"Member5": [
68,
85,
102
],
"Member6": "EnumB"
}
也可以自定义Converter,需要继承JsonConverter类,官方链接。举例将上例中的值保存为16进制格式。
public class JsonDecimalHexConverter : JsonConverter<byte>
{
public override byte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string val= reader.GetString();
return System.Convert.ToByte(val, 16);
}
public override void Write(Utf8JsonWriter writer, byte value, JsonSerializerOptions options)
{
writer.WriteStringValue("0x" + value.ToString("x"));
}
}
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true,
Converters = { new JsonDecimalHexConverter()},
};
output:
{
"Member1": "0x11",
"M2": 34,
"Member3": 51,
"Member4": true,
"Member5": [
68,
85,
102
],
"Member6": 1
}
上述写法还可以这样使用特性标记。
[JsonConverter(typeof(JsonDecimalHexConverter))]
public byte Member1 { get; set; }