检查jobobject是否包含一个数组

本文关键字:数组 包含一 是否 jobobject 检查 | 更新日期: 2023-09-27 18:13:41

业务规则很简单。我们有一个方法,它接受一个对象作为对象。将其转换为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);

检查jobobject是否包含一个数组

这样怎么样?

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");
        }