繁体   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