![](/img/trans.png)
[英]How can I determine the class of an XML serialized object in C# before I deserialize it?
[英]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.