C# JSON复杂类型,可以是对象或对象数组
我试图处理一个对象,它可以是一个对象数组,也可以只是一个对象。仅当naics是对象而不是数组时,使用下面的代码才有效。我做错了什么 下面是我能想到的最简短的例子:C# JSON复杂类型,可以是对象或对象数组,c#,arrays,json,object,C#,Arrays,Json,Object,我试图处理一个对象,它可以是一个对象数组,也可以只是一个对象。仅当naics是对象而不是数组时,使用下面的代码才有效。我做错了什么 下面是我能想到的最简短的例子: [{ "section": "52.219-1.b", "naics": [{ "naicsName": "Engineering Services", "isPrimary": true, "ExcpCou
[{
"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();
}
[JsonProperty(“naics”,NullValueHandling=NullValueHandling.Ignore)]
公共应答Naics Naics{get;set;}
公共部分结构应答器
{
公众回答;
公共回答[]naikarray;
公共静态隐式运算符AnswerNaics(AnswerNaic Naic)=>新的AnswerNaics{Naic=Naic};
公共静态隐式运算符AnswerNaics(AnswerNaic[]NaicArray)=>新的AnswerNaics{NaicArray=NaicArray};
}
公共部分类应答器
{
[JsonProperty(“naicsName”)]
公共字符串NaicsName{get;set;}
[JsonProperty(“hasSizeChanged”)]
公共字符串hasizechanged{get;set;}
[JsonProperty(“iPrimary”)]
公共bool IsPrimary{get;set;}
[JsonProperty(“ExcpCounter”,NullValueHandling=NullValueHandling.Ignore)]
公共long?ExcpCounter{get;set;}
[JsonProperty(“isSmallBusiness”)]
公共字符串{get;set;}
[JsonProperty(“naicsCode”)]
公共字符串NaicsCode{get;set;}
}
内部类NaicConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型t)=>t==typeof(AnswerNaics)| | t==typeof(AnswerNaics?);
公共重写对象ReadJson(JsonReader阅读器,类型t,对象existingValue,JsonSerializer序列化程序)
{
开关(reader.TokenType)
{
案例JsonToken.StartObject:
var objectValue=serializer.Deserialize(读取器);
返回新的AnswerNaics{Naic=objectValue};
案例JsonToken.StartArray:
var arrayValue=序列化程序。反序列化(读取器);
返回新的应答{naikarray=arrayValue};
}
抛出新异常(“无法解组类型应答”);
}
public override void WriteJson(JsonWriter编写器、对象非类型化值、JsonSerializer序列化器)
{
var值=(AnswerNaics)非类型值;
如果(value.NaicArray!=null)
{
serializer.Serialize(writer,value.NaicArray);
返回;
}
如果(value.Naic!=null)
{
serializer.Serialize(writer,value.Naic);
返回;
}
抛出新异常(“无法封送Naics类型”);
}
public static readonly naicconverter Singleton=new naicconverter();
}
我有更多的对象或数组节点,但我只是想找出一个可以应用于所有这些节点的节点。由于您无法更改传入的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();
}
}
公共类NaicConverter:JsonConverter
{
公共覆盖bool CanConvert(类型t)=>t==typeof(Naics);
公共重写对象ReadJson(JsonReader阅读器,类型t,对象existingValue,JsonSerializer序列化程序)
{
var naics=新的naics();
开关(reader.TokenType)
{
案例JsonToken.StartObject:
//我们知道这是一个对象,所以序列化一个Naics
Add(序列化程序.反序列化(读取器));
打破
案例JsonToken.StartArray:
//我们知道这是一个对象,所以序列化多个NAIC
foreach(序列化程序中的var naic.反序列化(读取器))
{
添加(naic);
}
打破
}
返回naics;
}
public override void WriteJson(JsonWriter编写器、对象非类型化值、JsonSerializer序列化器)
{
抛出新的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; }
}
公共类根目录
{
公共字符串部分{get;set;}
[JsonConverter(类型(NAICconverter))]
公共Naics Naics{get;set;}
}
//这并不理想,但它又快又脏,应该让你开始
公共类Naics:列表
{
}
公共类Naic
{
公共字符串NaicsName{get;set;}
公共bool IsPrimary{get;set;}
公共字符串{get;set;}
公共长代码{get;set;}
}
最后,要反序列化:
var settings = new JsonSerializerSettings {Converters = {new NaicsConverter()}};
var root = JsonConvert.DeserializeObject<Root[]>(Json, settings);
var settings=newjsonserializersettings{Converters={new naicconverter()};
var root=JsonConvert.DeserializeObject(Json,设置);
现在,您的对象将被序列化到列表中,但作为单个项。您可以使用类中的动态字段解决此问题 以JSON为例:
[
{
"field1": "val1",
"nested": [
{
"nestedField": "val2"
},
{
"nestedField": "val3"
}
]
},
{
"field1": "val4",
"nested":
{
"nestedField": "val5"
}
}
]
nested
字段首先是一个包含两个对象的数组,第二个外观是一个对象。(类似于您发布的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; }
}
公共类根对象
{
公共字符串字段1{get;set;}
公共动态嵌套{get;set;}
公共列表嵌套对象
{
得到
{
if(嵌套的是JArray)
{
返回JsonConvert.DeserializeObject(nested.ToString());
}
var obj=JsonConvert.DeserializeObject(nested.ToString());
返回新列表{obj};
}
}
}
公共类嵌套对象
{
公共字符串嵌套字段{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);
}
}
var objectList=JsonConvert.DeserializeObject(“some_json”);
foreach(objectList中的var v)
{
foreach(v.NestedObjects中的变量n)
{
控制台写入线(n.nestedField);
}
}
唯一的更改是NestedObjects
ready only属性的实现。它检查动态对象是否为J