业务规则很简单。我们有一个方法,它接受一个对象作为对象。将其转换为c# poco。
json需要表示单个对象。
不允许数组。如果你需要做三次,调用这个方法三次
例如这是合法的json:
{
"CustomerId": 669616948,
"FirstName": "ERIC",
"LastName": "TEST2",
"BirthYear": 0,
"BirthMonth": 0,
"CustomerState": 0,
"LegalAddressState": null,
"Username": "ERIC2222"
}
this would not:
{
"Participants": [
{
"CustomerId": 669616948,
"FirstName": "ERIC",
"LastName": "TEST2",
"BirthYear": 0,
"BirthMonth": 0,
"CustomerState": 0,
"LegalAddressState": null,
"Username": "ERIC2222"
}
]
}
当前,当它试图转换为poco时抛出一个异常,虽然我们可以处理异常,但我正在寻找一种方法来检测jobobject是否包含数组并优雅地退出。
所以上面的json只是一个JObject的表示,但它是一个JObject。
我能想到的最好的就是一个微不足道的字符串检查。
JObject.ToString().Contains("[")
关于如何做数组检查有什么想法吗?如果我能把它转换成JToken,那么我可以这样做(temp是JToken类型):
temp.Type == JTokenType.Array
TIA
按要求这里是转换。payload是一个jobobject。
var customer = payload.ToObject<Customer>(_serializer);
这样怎么样?
dynamic value = jToken["Participants"];
if (value != null && value is JArray)
{
//gracefully exit.
}
您总是可以编写一个自定义的JsonConverter
,它遍行json树(使用类似于此回答https://stackoverflow.com/a/19646950/1165998中描述的技术),检查JArray
的类型和值类型,如果是,则返回null:
public class ProhibitArraysConverter<T> : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
var jsonObject = JToken.Load(reader);
if (ContainsArray(jsonObject))
return null;
T target = (T)Activator.CreateInstance(objectType);
serializer.Populate(jsonObject.CreateReader(), target);
return target;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
private static bool ContainsArray(JToken containerToken)
{
if (containerToken.Type == JTokenType.Object)
{
foreach (JProperty child in containerToken.Children<JProperty>())
{
if (child.Type == JTokenType.Array ||
child.Value.Type == JTokenType.Array)
{
return true;
}
ContainsArray(child.Value);
}
}
else if (containerToken.Type == JTokenType.Array)
{
return true;
}
return false;
}
}
这将返回第一个示例中反序列化的数据,第二个示例中返回null。
我不太清楚你们的要求。但这是一种方法:
[TestMethod]
public void DeserializeTest()
{
var jsonStr1 = "{"CustomerId": 669616948,"FirstName": "ERIC","LastName": "TEST2","BirthYear": 0,"BirthMonth": 0,"CustomerState": 0,"LegalAddressState": null,"Username": "ERIC2222"}";
JToken token1 = JToken.Parse(jsonStr1);
var participantsFromToken1 = token1["Participants"];
Console.WriteLine(participantsFromToken1 != null && participantsFromToken1.Type == JTokenType.Array
? "Hey, token1 is an array"
: "Hey, token1 is not an array");
var jsonStr2 =
"{"Participants": [{"CustomerId": 669616948,"FirstName": "ERIC","LastName": "TEST2","BirthYear": 0,"BirthMonth": 0,"CustomerState": 0,"LegalAddressState": null,"Username": "ERIC2222"}]}";
JToken token2 = JToken.Parse(jsonStr2);
var participantsFromToken2 = token2["Participants"];
Console.WriteLine(participantsFromToken2 != null && participantsFromToken2.Type == JTokenType.Array
? "Hey, token2 is an array"
: "Hey, token2 is not an array");
}