簡體   English   中英

c#-分兩步對Json進行反序列化

[英]c# - Deserialize a Json in two steps

我想分兩步對Json進行反序列化,因為我必須閱讀第一部分才能知道它是哪種Object。

我必須閱讀這種Json的文章:

{"header":3,"data":{"result":"myResult"}}

這樣更易讀

{
    "header":3,
    "data":{
        "result":"myResult"
    }
}

我在名為ProtocolHeader的類中反序列化此Json:

public class ProtocolHeader
{
    [JsonProperty("header")]
    public int Header { get; set; }

    [JsonProperty("data")]
    public string Data { get; set; }
}

為此,我使用以下代碼:

JsonConvert.DeserializeObject<ProtocolHeader>(Json)

根據Header的值,我將選擇不同的類來反序列化文件的末尾。

例如我可以再上一個課

public class ProtocolResult
{
    [JsonProperty("result")]
    public string Result{ get; set; }
}

或那樣

public class ProtocolError
{
    [JsonProperty("errorNumber")]
    public int ErrorNumber{ get; set; }

    [JsonProperty("additionalInformation")]
    public string AdditionalInformation{ get; set; }
}

您有兩個步驟來分離反序列化對象的想法嗎?

謝謝

你可以上3節課。 一個具有所有字段的通用類(不是基類),然后是ProtocolResult和ProtocolError

然后對每個對象執行隱式轉換。 您還可以將IsError getter放入普通類中,以決定如何使用它。

您可以使用閱讀器僅在需要時閱讀,然后跳出閱讀器進行真正的反序列化。

可能比先反序列化為簡單對象然后反序列化為實際對象要好得多,但這是另一種選擇。

您可能可以對此稍作調整。

string json = @"{""header"":3,""data"":{""result"":""myResult""}}";

using (var stringReader = new StringReader(json))
{
    using (var jsonReader = new JsonTextReader(stringReader))
    {
        while (jsonReader.Read())
        {
            if (jsonReader.TokenType == JsonToken.PropertyName 
                && jsonReader.Value != null
                && jsonReader.Value.ToString() == "header")
            {
                jsonReader.Read();
                int header = Convert.ToInt32(jsonReader.Value);
                switch (header)
                {
                    case 1:
                        // Deserialize as type 1
                        break;
                    case 2:
                        // Deserialize as type 2
                        break;
                    case 3:
                        // Deserialize as type 3
                        break;
                }
                break;
            }
        }
    }
}

選項1:在data類中不使用抽象基類。

我發現最簡單的方法如下:

  1. 使用JToken作為未知對象的字段類型聲明您的類。

     [JsonObject(MemberSerialization.OptIn)] public class ProtocolHeader { [JsonProperty("header")] private int _header; [JsonProperty("data")] private JToken _data; } 
  2. 公開屬性中的專用數據。

     public ProtocolResult Result { get { if (_data == null || _header != ResultHeaderValue) return null; return _data.ToObject<ProtocolResult>(); } } public ProtocolError Error { get { if (_data == null || _header != ErrorHeaderValue) return null; return _data.ToObject<ProtocolError>(); } } 

選項2:對data類使用抽象基類。

另一種選擇是為各種數據類型創建抽象基類,並在抽象基類中創建靜態方法以執行類型選擇和適當的反序列化。 當類型信息包含在對象本身中時(例如,如果headerdata對象內部的屬性),這特別有用。

  1. LoadBalancerConfiguration<T>._healthMonitor字段的類型為JObject ,但是同一類中的HealthMonitor屬性返回一個HealthMonitor對象。
  2. HealthMonitor.FromJObject方法執行實際的反序列化。

暫無
暫無

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

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