为何NewtonsoftJson的TypeNameHandling对Guid不生效及如何处理
原因分析
Newtonsoft.Json 的 TypeNameHandling 配置仅对自定义类、复杂对象生效,Guid 属于内置基础值类型,默认会直接序列化为JSON字符串,不会附加$type元数据,因此会出现序列化结果无类型标记、非泛型反序列化强制转换失败的问题。
解决方案
通过自定义JsonConverter强制Guid按照你需要的带类型标记的结构序列化,同时适配非泛型反序列化逻辑:
步骤1:实现自定义Guid转换类
using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class GuidTypeConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(Guid); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteStartObject(); // 可根据需要自定义$type的取值,下方示例为.NET Core下的系统Guid类型标识 writer.WritePropertyName("$type"); writer.WriteValue("System.Guid, System.Private.CoreLib"); writer.WritePropertyName("value"); writer.WriteValue(((Guid)value).ToString("N")); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.String) { // 兼容旧的纯字符串格式Guid序列化结果 return Guid.Parse(reader.Value.ToString()); } if (reader.TokenType == JsonToken.StartObject) { JObject guidObj = JObject.Load(reader); return Guid.Parse(guidObj["value"].ToString()); } throw new JsonSerializationException("不支持的Guid序列化格式"); } }
步骤2:配置JsonSerializerSettings使用自定义转换器
将上述转换器加入序列化配置的转换器集合即可,改造后的示例代码如下:
using System; using Newtonsoft.Json; namespace ConsoleApplication1 { internal class Program { public static void Main(string[] args) { var jsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, Converters = new List<JsonConverter> { new GuidTypeConverter() } }; var guid = Guid.NewGuid(); var serialised = JsonConvert.SerializeObject(guid, jsonSettings); Console.WriteLine(serialised); // 输出示例:{"$type":"System.Guid, System.Private.CoreLib","value":"34861761826d4419a2084ef161992616"} // 非泛型反序列化可正常转换 var deserializedGuid = (Guid)JsonConvert.DeserializeObject(serialised, jsonSettings); Console.WriteLine(deserializedGuid == guid); // 输出True } } }
注意事项
如果运行环境为.NET Framework,需要将WriteJson中的$type取值调整为System.Guid, mscorlib,如果不需要严格匹配系统类型标识,也可以直接修改为你预期的Newtonsoft.Json.Guid。
内容的提问来源于stack exchange,提问作者Andrey Golubev
相关产品推荐
相关产品推荐

