将 JSON 反序列化为包含动态 属性 和 System.Text.Json 的 class

Deserializing JSON to a class containing a dynamic property with System.Text.Json

objective 是反序列化 JSON 对包含动态部分的包装器响应 class 的响应,使用新的 System.Text.Json 来自 NET Core 3.

的库

也就是

{
    "fixedProperty": "Hello",
    "dynamicProperty": { 
        "attributeOne": "One",
        "attributeTwo": "Two",
    }
}

public class MyResponseClass
{
    public string FixedProperty { get; set; }
    public dynamic DynamicProperty { get; set; }  
}

// Where the dynamic property is one of the classes.
// (MyDataClassOne in the particular JSON example above)
public class MyDataClassOne
{
    public string AttributeOne { get; set; }
    public string AttributeTwo { get; set; }  
}

public class MyDataClassTwo
{
    public string AttributeThree { get; set; }
    public string AttributeFour { get; set; }  
}

...

响应中动态 属性 的类型总是预先知道的(取决于请求),并且是三种不同的 classes 之一。

无法找到一种干净的方法来做到这一点,除了没有一个包装器 class 和动态 属性 但每个案例都有多个不同的响应 classes (这显然工作正常但不是所需的解决方案)。

编辑: 解决方案是使用泛型。

这样的怎么样?

var myResponseClass = new MyResponseClass();

dynamic myClass = JsonSerializer.Deserialize<ExpandoObject>("{\"fixedProperty\":\"Hello\",\"dynamicProperty\": {\"attributeOne\":\"One\",\"attributeTwo\":\"Two\"}}");
dynamic myProperty = JsonSerializer.Deserialize<ExpandoObject>(myClass.dynamicProperty.ToString());

myResponseClass.FixedProperty = myClass.fixedProperty.ToString();
myResponseClass.DynamicProperty = myProperty;

由于响应中动态 属性 的类型总是事先已知(取决于请求),您可以使用 generic根对象:

public class MyResponseClass<T> 
{ 
    public string FixedProperty { get; set; } 
    public T DynamicProperty { get; set; } 
}

然后将 T 声明为所需的任何已知具体 class,例如

var root = JsonSerializer.Deserialize<MyResponseClass<MyDataClassOne>>(responseString);
var fixedProperty = root.fixedProperty;
var attributeOne = root.DynamicProperty?.AttributeOne;