You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:25:19