问题描述
我正在尝试处理一个对象,该对象可以是对象数组,也可以只是对象。仅当naic是对象而不是数组时,才可以使用下面的代码。我在做什么错了?
I am trying to process an object that can be either an array of object or just the object. Using the code below only works when the naics is an object and not an array. What am I doing wrong?
这是我能想到的最短的例子:
Here is the shortest example I can come up with:
[{
"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",
"isPrimary": true,
"ExcpCounter": 2,
"isSmallBusiness": "Y",
"naicsCode": 541330
}
]
},
{
"section": "52.219-1.b",
"naics": {
"naicsName": "Janitorial Services",
"isPrimary": true,
"isSmallBusiness": "Y",
"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();
}
我有更多的对象或数组节点,但是我只是想弄清楚
I have more object or array nodes, but I am just trying to figure out one to be able to apply to all of them.
推荐答案
由于您无法更改传入的JSON,因此需要而是自定义转换器。例如这样的东西:
Since you cannot change the incoming JSON, you're going to need a custom converter instead. Something like this for example:
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);
现在,您的对象将被序列化到列表中,但作为单个项目。
Now your object will get serialised into the list, but as a single item.
这篇关于JSON复杂类型,可以是一个对象或对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!