簡體   English   中英

C#如何確定要反序列化的對象

[英]C# how to determine which object to deserialize to

我正在調用返回JSON負載的Web API。 其中一個字段有時是布爾值,有時是JSON對象本身。

有沒有辦法確定我是否正在反序列化一個類(文檔)或有時只是一個布爾值的字段? 當我得到布爾值時,它將引發錯誤。

我以為我可以嘗試一堂課,如果有錯誤,請嘗試另一堂課,但似乎應該有更好的方法來做到這一點。 示例JSON將是

{
  "field1":"value1",
  "field2":false
}

VS

{
  "field1":"value1",
  "field2":
  {
    "field21":"value21",
    "field22":"value22"
  }
}
[TestClass]
public class UnitTest2
{
    [TestMethod]
    public void Test()
    {
        var json1 = "{\"field1\":\"value1\",\"field2\":true}";
        var deserializedWithBool = JsonConvert.DeserializeObject<ObjectJson>(json1);

        var json2 = "{\"field1\":\"value1\",\"field2\": { \"field21\" : \"value21\", \"field22\" : \"value22\"}}";
        var deserializedWithObject = JsonConvert.DeserializeObject<ObjectJson>(json2);

        Assert.AreEqual(true, deserializedWithBool.field2.field2BoolResult);
        Assert.AreEqual("value21", deserializedWithObject.field2.field21);
    }
}

public class ObjectJson
{
    public string field1 { get; set; }

    [JsonConverter(typeof(FieldJsonConverter))]
    public FieldResult field2 { get; set; }
}

public class FieldResult
{
    public bool? field2BoolResult { get; set; }
    public string field21 { get; set; }
    public string field22 { get; set; }
}

public class FieldJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(FieldResult));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Boolean)
        {
            return new FieldResult() { field2BoolResult  = (bool)(JValue)token };
        }
        else if (token.Type == JTokenType.Object)
        {
            return token.ToObject<FieldResult>();
        }

        throw new InvalidOperationException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

使用json.net,然后在上面創建Custom jsonConverter示例:

https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm

您還可以使用通用類型來存儲Field2 ...

    public class MyClassBase<T>
    {
        public string Field1 { get; set; }
        public T Field2 { get; set; }
    }

    public class Field
    {
        public string Field21 { get; set; }
        public string Field22 { get; set; }
    }

    public class TestJsonDeserialise
    {
        public void Run()
        {
            var json1 = @"{
          'field1':'value1',
          'field2':
          {
          'field21':'value21',
          'field22':'value22'
          }
        }";

            var json2 = @"{
          'field1':'value1',
          'field2':false 
        }";

            var json = json2;
            var field2 = JObject.Parse(json)["field2"];

            object myClass = null;
            switch (field2.Type)
            {
                case JTokenType.Object:
                    myClass = GetMyClass<MyClassBase<Field>>(json);
                    break;
                case JTokenType.Boolean:
                    myClass = GetMyClass<MyClassBase<bool>>(json);
                    break;
            }

            switch (myClass)
            {
                case MyClassBase<Field> fieldResult:
                    //When FieldResult then do stuff
                    Console.WriteLine("You got an Object");
                    break;
                case MyClassBase<bool> boolResult:
                    //You got a bool back
                    Console.WriteLine("You got a bool");
                    break;
            }
        }

        public T GetMyClass<T>(string json)
        {
            return JsonConvert.DeserializeObject<T>(json);
        }
    }

您應該自己實現JsonConverter類,並使用屬性[JsonConverter(typeof(YourJsonConverter))]

然后,您可以將自己的實現應用於反序列化屬性。

您可以重寫ReadJson方法以檢查對象的類型,並采取相應的措施。

暫無
暫無

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

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