簡體   English   中英

C#Newtonsoft-根據屬性名稱將JSON反序列化為具體的

[英]C# Newtonsoft - Deserialize JSON into concrete based on property name

我有一個JSON,我想反序列化為A類; 字段之一是一組抽象類B (有一些具體的實現)。 是否可以在構建自定義JsonConverter的情況下正確地反序列化抽象類數組? 理想情況下,JSON.net本身並不冗長,例如使用TypeNameHandling.All ...,但是我沒有那條特定的途徑可以工作。

沒有在序列化時訪問JSON(如果可以的話, TypeNameHandling會很好用),但只能在反序列化時使用。

具體來說:

public class A  // the top-level class to deserialize
{
    public B[] arr;
    // other members...
}
public abstract class B
{
    // ...some fields...
}
public class C : B 
{
    // a concrete implementation of B
}
public class D : B 
{
    // another concrete implementation of B
}

而且我收到了一個看起來像這樣的JSON:

{
  "arr" : [
   {
     // a C object
   },
   {
     // a D object
   }
  ]
}

我知道您可以使用下面的XML反序列化來有效地干凈地做這樣的事情: 我幾乎在尋找與JSON類似的東西。

// tells the deserializer to deserialize the object with field name "C" as a 
// class C, and field name "D" as a D
[XmlElement("C", Type = typeof(C))]
[XmlElement("D", Type = typeof(D))]
public B[] arr;

由於您無法修改JSON以使用TypeNameHandling ,因此需要創建一個自定義轉換器,以檢查屬性以確定要返回的類型。 假設您的派生類如下所示:

public class C : B
{
    public string CProperty { get; set; }
}

public class D : B
{
    public string DProperty { get; set; }
}

您可能有一個自定義轉換器類,如下所示:

public class BConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type type, 
        object value, JsonSerializer serializer)
    {
        JObject jobject = JObject.Load(reader);
        if (jobject.ContainsKey("CProperty"))
        {
            return jobject.ToObject<C>(serializer);
        }

        if (jobject.ContainsKey("DProperty"))
        {
            return jobject.ToObject<D>(serializer);
        }

        throw new Exception("Um, this is some other type!");
    }

    public override bool CanConvert(Type type) => type == typeof(B);
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
        => throw new NotImplementedException();
}

現在您可以像這樣反序列化:

var result = JsonConvert.DeserializeObject<A>(json, new BConverter());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM