.NET 5 ASP REST服务从Newtonsoft.Json迁移至System.Text.Json时的Guid反序列化问题
解决System.Text.Json反序列化无分隔符GUID的问题
这个问题的核心在于System.Text.Json默认仅支持带短横线的标准GUID格式,而Newtonsoft.Json会自动兼容无分隔符的GUID字符串。要让System.Text.Json实现相同的兼容行为,我们可以通过自定义一个GUID转换器来解决。
步骤1:创建自定义Guid转换器
我们需要实现一个JsonConverter<Guid>,在反序列化逻辑中先尝试标准格式解析,失败则处理无分隔符的情况:
using System; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; public class FlexibleGuidConverter : JsonConverter<Guid> { public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var guidString = reader.GetString(); if (string.IsNullOrEmpty(guidString)) { return Guid.Empty; } // 先尝试标准格式解析 if (Guid.TryParse(guidString, out var result)) { return result; } // 清理字符串(移除所有非十六进制字符),尝试无分隔符格式解析 var cleanedGuid = new string(guidString.Where(char.IsLetterOrDigit).ToArray()); if (Guid.TryParseExact(cleanedGuid, "N", out result)) { return result; } // 解析失败时抛出异常,和System.Text.Json默认行为保持一致 throw new FormatException($"无法将字符串 '{guidString}' 转换为Guid类型"); } public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options) { // 序列化时输出标准带短横线的GUID格式(也可以根据需求改为无分隔符的"N"格式) writer.WriteStringValue(value.ToString("D")); } }
步骤2:将转换器注册到服务配置中
修改你在ConfigureServices里的AddJsonOptions配置,把自定义转换器添加进去:
services.AddControllers( options => { options.ValueProviderFactories.Add(new ClaimValueProviderFactory()); }).AddJsonOptions(options => { options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; // 注册自定义GUID转换器 options.JsonSerializerOptions.Converters.Add(new FlexibleGuidConverter()); });
验证效果
现在用你提供的测试代码验证:
var json = "{\"AuthorId\":\"6917d697c1ab4fb7b2978b2a23100bfc\",\"Title\":\"test title\"}"; var result = System.Text.Json.JsonSerializer.Deserialize<Post>(json); // 此时result.AuthorId会正确解析为对应的Guid值,不再抛出异常或返回null
这个转换器同时兼容标准带短横线和无分隔符的GUID格式,完全匹配Newtonsoft.Json的行为。如果需要支持更多GUID格式(比如带括号、大写格式等),可以在Read方法里扩展TryParseExact的格式参数,添加"B"、"P"、"X"等格式即可。
内容的提问来源于stack exchange,提问作者Misiu
相关产品推荐
相关产品推荐

