Newtonsoft反序列化Opc.Ua.NodeId转System.Type报错的解决咨询
解决Newtonsoft.Json反序列化第三方类型到System.Type的异常问题
问题原因
Newtonsoft.Json默认通过Type.GetType(string)解析类型字符串:
- 系统类型(如
System.Boolean)属于核心程序集,无需指定程序集名称即可被找到 - 第三方类型(如
Opc.Ua.NodeId)仅提供类型全名时,Type.GetType无法定位到对应的程序集,因此抛出转换异常
解决方案
方案一:修改JSON的Type字段,补充程序集名称
在类型全名后添加程序集标识(格式:类型全名, 程序集名称),Opc.Ua.NodeId对应的程序集通常为Opc.Ua.Core,修改后的JSON示例:
{ "Status": { "Type": "System.Boolean", "Value": true }, "ServerId": { "Type": "System.String", "Value": { "olaBola": "ns=3;i=422970276" } }, "SessionId": { "Type": "Opc.Ua.NodeId, Opc.Ua.Core", "Value": { "Identifier": "ns=3;i=422970276" } } }
注意:程序集名称需与项目中引用的Opc.Ua程序集名称一致,可通过查看项目引用的属性确认
方案二:自定义JsonConverter处理Type反序列化
如果无法修改JSON内容,可自定义转换器,手动遍历已加载的程序集查找目标类型:
1. 实现自定义Type转换器
public class TypeConverter : JsonConverter<Type> { public override Type ReadJson(JsonReader reader, Type objectType, Type existingValue, bool hasExistingValue, JsonSerializer serializer) { var typeName = reader.Value as string; if (string.IsNullOrEmpty(typeName)) return null; // 先尝试默认方式查找类型 var targetType = Type.GetType(typeName); if (targetType != null) return targetType; // 遍历当前AppDomain已加载的程序集查找类型 foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { targetType = assembly.GetType(typeName); if (targetType != null) return targetType; } throw new JsonSerializationException($"无法找到指定类型: {typeName}"); } public override void WriteJson(JsonWriter writer, Type value, JsonSerializer serializer) { // 序列化时输出类型全名(如需包含程序集可改为 value.AssemblyQualifiedName) writer.WriteValue(value.FullName); } }
2. 应用转换器
有两种方式可以应用这个转换器:
- 方式一:通过特性标记属性
修改ExtendedAttribute类,在Type属性上添加转换器特性:public class ExtendedAttribute { [JsonConverter(typeof(TypeConverter))] public Type? Type { get; set; } public object? Value { get; set; } } - 方式二:反序列化时传入配置
在调用反序列化方法时,传入包含自定义转换器的设置:var serializerSettings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new TypeConverter() } }; var result = JsonConvert.DeserializeObject<Dictionary<string, ExtendedAttribute>>(jsonText, serializerSettings);
额外说明
解决Type字段的转换问题后,若Value字段无法正确反序列化为Opc.Ua.NodeId类型,需确保NodeId类已被Newtonsoft.Json正确识别——如果NodeId有自定义的序列化逻辑,可添加对应的JsonConverter或确保类具备无参构造函数、可公开访问的属性。
内容的提问来源于stack exchange,提问作者Amit Kumar
相关产品推荐
相关产品推荐

