JSON复杂类型,可以是一个对象或对象数组

我正在尝试处理一个对象,该对象可以是对象数组,也可以只是对象。仅当naic是对象而不是数组时,才可以使用下面的代码。我在做什么错了?

这是我能想到的最短的例子:

[{
        "section": "52.219-1.b","naics": [{
                "naicsname": "Engineering Services","isPrimary": true,"ExcpCounter": 1,"isSmallBusiness": "Y","naicsCode": 541330
            },{
                "naicsname": "Military and Aerospace Equipment and Military Weapons","ExcpCounter": 2,"naicsCode": 541330
            }
        ]
    },{
        "section": "52.219-1.b","naics": {
            "naicsname": "Janitorial Services","naicsCode": 561720
        }
    }
]

我将只有一种类型,但是我在数组中强行将其强制为快速类型。

我的课程是:

[JsonProperty("naics",NullValueHandling = NullValueHandling.Ignore)]
public AnswerNaics Naics { get; set; }

public partial struct AnswerNaics
{
    public AnswerNaic Naic;
    public AnswerNaic[] NaicArray;

    public static implicit operator AnswerNaics(AnswerNaic Naic) => new AnswerNaics { Naic = Naic };
    public static implicit operator AnswerNaics(AnswerNaic[] NaicArray) => new AnswerNaics { NaicArray = NaicArray };
}

public partial class AnswerNaic
{
    [JsonProperty("naicsname")]
    public string Naicsname { get; set; }

    [JsonProperty("hasSizeChanged")]
    public string HasSizeChanged { get; set; }

    [JsonProperty("isPrimary")]
    public bool IsPrimary { get; set; }

    [JsonProperty("ExcpCounter",NullValueHandling = NullValueHandling.Ignore)]
    public long? ExcpCounter { get; set; }

    [JsonProperty("isSmallBusiness")]
    public string IsSmallBusiness { get; set; }

    [JsonProperty("naicsCode")]
    public string NaicsCode { get; set; }
}

internal class NaicsConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(AnswerNaics) || t == typeof(AnswerNaics?);

    public override object ReadJson(JsonReader reader,Type t,object existingValue,JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.StartObject:
                var objectvalue = serializer.Deserialize<AnswerNaic>(reader);
                return new AnswerNaics { Naic = objectvalue };
            case JsonToken.StartArray:
                var arrayValue = serializer.Deserialize<AnswerNaic[]>(reader);
                return new AnswerNaics { NaicArray = arrayValue };
        }
        throw new Exception("Cannot unmarshal type AnswerNaics");
    }

    public override void WriteJson(JsonWriter writer,object untypedValue,JsonSerializer serializer)
    {
        var value = (AnswerNaics)untypedValue;
        if (value.NaicArray != null)
        {
            serializer.Serialize(writer,value.NaicArray);
            return;
        }
        if (value.Naic != null)
        {
            serializer.Serialize(writer,value.Naic);
            return;
        }
        throw new Exception("Cannot marshal type Naics");
    }

    public static readonly NaicsConverter Singleton = new NaicsConverter();
}

我有更多的对象或数组节点,但我只是想找出一个能够应用于所有对象或数组的节点。

tanquanxin99 回答:JSON复杂类型,可以是一个对象或对象数组

由于您无法更改传入的JSON,因此需要一个自定义转换器。例如:

public class NaicsConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(Naics);

    public override object ReadJson(JsonReader reader,Type t,object existingValue,JsonSerializer serializer)
    {
        var naics = new Naics();

        switch (reader.TokenType)
        {
            case JsonToken.StartObject:
                // We know this is an object,so serialise a single Naics
                naics.Add(serializer.Deserialize<Naic>(reader));
                break;

            case JsonToken.StartArray:
                // We know this is an object,so serialise multiple Naics
                foreach(var naic in serializer.Deserialize<List<Naic>>(reader))
                {
                    naics.Add(naic);
                }
                break;
        }

        return naics;
    }

    public override void WriteJson(JsonWriter writer,object untypedValue,JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

以及支持类:

public class Root
{
    public string Section { get; set; }

    [JsonConverter(typeof(NaicsConverter))]
    public Naics Naics { get; set; }
}

// This isn't ideal,but it's quick and dirty and should get you started
public class Naics : List<Naic>
{

}

public class Naic
{
    public string NaicsName { get; set; }
    public bool IsPrimary { get; set; }
    public string IsSmallBusiness { get; set; }
    public long NaicsCode { get; set; }
}

最后,要反序列化:

var settings = new JsonSerializerSettings {Converters = {new NaicsConverter()}};

var root = JsonConvert.DeserializeObject<Root[]>(Json,settings);

现在,您的对象将被序列化到列表中,但作为一个项目。

,

您可以在课堂上使用动态字段来解决此问题。

考虑此JSON:

[
  {
    "field1": "val1","nested": [
      {
        "nestedField": "val2"
      },{
        "nestedField": "val3"
      }
    ]
  },{
    "field1": "val4","nested": 
      {
        "nestedField": "val5"
      }          
  }
]

nested字段是第一个包含2个对象的数组,第二个出现是单个对象。 (类似于您发布的JSON)

所以类表示形式如下:

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

        public dynamic nested { get; set; }  

        public List<NestedObject> NestedObjects
        {
            get
            {
               if(nested is JArray)
               {
                    return JsonConvert.DeserializeObject<List<NestedObject>>(nested.ToString());
               }

               var obj = JsonConvert.DeserializeObject<NestedObject>(nested.ToString());
               return new List<NestedObject> { obj };
            }
        }
    }

    public class NestedObject
    {
        public string nestedField { get; set; }
    }

使用Newtonsoft JSON,反序列化代码很简单:

var objectList = JsonConvert.DeserializeObject<List<RootObject>>("some_json");

foreach(var v in objectList)
{
    foreach(var n in v.NestedObjects)
    {
        Console.WriteLine(n.nestedField);
    }
}

唯一的变化是NestedObjects仅就绪属性的实现。它检查动态对象是JArray还是对象。无论如何,它都会返回List的嵌套对象。

本文链接:https://www.f2er.com/3158091.html

大家都在问