反序列化时为缺失的JSON属性设置默认值的实现方法
实现JSON反序列化时自动用Uid填充缺失的ServiceName属性
你需要让ServiceName成为可选属性,当JSON中缺失该字段时自动用Uid的值填充,同时无需手动解析JSON DOM,这里有两种简便的自动反序列化实现方式:
方法一:利用带可选参数的构造函数(推荐)
修改ServiceConfig record,添加标记[JsonConstructor]的构造函数,将ServiceName设为可选参数,在构造逻辑中处理默认值:
using System.Text.Json.Serialization; public record ServiceConfig { public required string Type { get; init; } public required string Uid { get; init; } public string ServiceName { get; init; } [JsonConstructor] public ServiceConfig(string type, string uid, string? serviceName = null) { Type = type; Uid = uid; // 若ServiceName为null(JSON中缺失该字段),则用Uid填充 ServiceName = serviceName ?? uid; } }
反序列化时,System.Text.Json会优先使用这个标记的构造函数:
- 当JSON包含
ServiceName时,传入对应值; - 当JSON缺失
ServiceName时,参数serviceName为null,自动用uid的值赋值给ServiceName。
方法二:自定义JsonConverter
如果需要更灵活的控制,可以实现自定义JsonConverter<ServiceConfig>,在反序列化过程中处理字段填充逻辑:
using System.Text.Json; using System.Text.Json.Serialization; public class ServiceConfigConverter : JsonConverter<ServiceConfig> { public override ServiceConfig? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var temp = JsonSerializer.Deserialize<JsonElement>(ref reader, options); string type = temp.GetProperty("Type").GetString()!; string uid = temp.GetProperty("Uid").GetString()!; // 尝试获取ServiceName,不存在则用Uid string serviceName = temp.TryGetProperty("ServiceName", out var serviceNameElem) ? serviceNameElem.GetString()! : uid; return new ServiceConfig(type, uid, serviceName); } public override void Write(Utf8JsonWriter writer, ServiceConfig value, JsonSerializerOptions options) { // 序列化逻辑按需实现,这里用默认序列化 JsonSerializer.Serialize(writer, value, options); } }
使用时需在JsonSerializerOptions中注册转换器:
var options = new JsonSerializerOptions(); options.Converters.Add(new ServiceConfigConverter()); var cfg = JsonSerializer.Deserialize<ServiceConfig>(stream, options);
这种方法代码量稍多,但适合复杂处理场景,同样无需手动解析完整DOM树。
内容的提问来源于stack exchange,提问作者Mr. Boy
相关产品推荐
相关产品推荐

