由于下面的示例非常详细,我先提出了抽象问题。
抽象的问题
我想反序列化不受我控制的类的两个属性。这些属性来自 int/foreign 类 NodeId 类型。有两个静态类提供公共字段作为常量。我想从 JSON 中反序列化给定静态类的名称,并从实例中的给定静态类中设置相应的值。
我希望能够从 JSON 中读取的内容:
{
"DataType": "Float",
"ValueRank": "Scalar"
}
我现在需要用 JSON 编写它可以工作的内容(这些是来自静态类的“翻译”值;有关更多详细信息,请参见完整示例):
{
"DataType": "i=10",
"ValueRank": -1
}
我的问题是:
- 我无法用 JsonConverter 属性装饰外部类的属性
- 我无法对类型做出反应,
int
或者NodeId
因为它太笼统
我的解决方法:
- 以某种方式用我的“外部”属性装饰外国类属性!?!?这可能吗?
- 编写一个自定义反序列化器,它通过反射对属性名称做出反应!?!?这可能吗?
如果上述解决方案都不起作用,我的工作是摆脱它:
- 从类派生并使用自定义反序列化器装饰派生类中的字段。
- 创建我自己的反序列化类,并使用我的类中的值创建外部类的实例。
包含所有细节的示例
我正在使用OPC 基金会的 OPC UA 堆栈中的一个类,我想反序列化它。我感兴趣的课程的摘录如下所示:
[DataContract(Namespace = "http://opcfoundation.org/UA/2008/02/Types.xsd")]
[GeneratedCode("Opc.Ua.ModelCompiler", "1.0.0.0")]
public class Argument : IEncodeable
{
...
[DataMember(Name = "DataType", IsRequired = false, Order = 2)]
public NodeId DataType { get; set; }
[DataMember(Name = "ValueRank", IsRequired = false, Order = 3)]
public int ValueRank { get; set; }
...
}
这种类在代码中的实例化如下所示:
new Argument() { DataType = DataTypeIds.Float, ValueRank = ValueRanks.Scalar },
用于常量的类如下所示:
[GeneratedCode("Opc.Ua.ModelCompiler", "1.0.0.0")]
public static class DataTypeIds
{
...
public static readonly NodeId Float; //returns string "i=10"
...
}
和这个:
public static class ValueRanks
{
...
public const int Scalar = -1;
...
}
创建Argument
硬编码实例非常简单直接。从 JSON 反序列化它会变得很棘手,因为我无法为属性配备自定义属性,也无法对 NodeId 和 int 类型做出反应。
提前致谢