我有一个包含以下数据的json字符串
"air:FlightOptionsList": {
"air:FlightOption": [{
"LegRef": "hx5kk+3R2BKABGzqAAAAAA==",
"Destination": "LHE",
"Origin": "DXB",
"air:Option": {
"Key": "hx5kk+3R2BKA/FzqAAAAAA==",
"TravelTime": "P0DT3H0M0S",
"air:BookingInfo": {
"BookingCode": "I",
"BookingCount": "7",
"CabinClass": "Economy",
"FareInfoRef": "hx5kk+3R2BKAzFzqAAAAAA==",
"SegmentRef": "hx5kk+3R2BKAtFzqAAAAAA=="
}
}
}, {
"LegRef": "hx5kk+3R2BKAFGzqAAAAAA==",
"Destination": "DXB",
"Origin": "LHE",
"air:Option": {
"Key": "hx5kk+3R2BKACGzqAAAAAA==",
"TravelTime": "P0DT11H30M0S",
"air:BookingInfo": [{
"BookingCode": "U",
"BookingCount": "7",
"CabinClass": "Economy",
"FareInfoRef": "hx5kk+3R2BKA+FzqAAAAAA==",
"SegmentRef": "hx5kk+3R2BKAvFzqAAAAAA=="
}, {
"BookingCode": "Y",
"BookingCount": "9",
"CabinClass": "Economy",
"FareInfoRef": "hx5kk+3R2BKA+FzqAAAAAA==",
"SegmentRef": "hx5kk+3R2BKAxFzqAAAAAA=="
}
],
"air:Connection": {
"SegmentIndex": "0"
}
}
}
]
}
我的班级结构如下:
public class FlightOptionsList
{
public List<FlightOption> FlightOption { get; set; }
}
public class FlightOption
{
public string LegRef { get; set; }
public string Destination { get; set; }
public string Origin { get; set; }
public Option Option { get; set; }
}
public class Option
{
public string Key { get; set; }
public string TravelTime { get; set; }
public List<BookingInfo> BookingInfo { get; set; }
public Connection Connection { get; set; }
}
public class BookingInfo
{
public string BookingCode { get; set; }
public string BookingCount { get; set; }
public string CabinClass { get; set; }
public string FareInfoRef { get; set; }
public string SegmentRef { get; set; }
}
我想反序列化它,但它给我一个错误如下:
无法将当前JSON对象(例如{“name”:“value”})反序列化为类型'System.Collections.Generic.List`1 [ParseSoapEnveloperReqRes.BookingInfo]',因为该类型需要JSON数组(例如[1,2,3])正确反序列化。 要修复此错误,请将JSON更改为JSON数组(例如[1,2,3])或更改反序列化类型,使其成为普通的.NET类型(例如,不是像整数这样的基本类型,而不是类似的集合类型可以从JSON对象反序列化的数组或List。 JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化。 路径'FlightOptionsList.FlightOption [0] .Option.BookingInfo.BookingCode',第394行,第59位。
这是因为,好像你看到了json字符串,FlightOptionsList.FlightOption [0] .Option。 BookingInfo 是一个对象,但在FlightOptionsList.FlightOption [1]您可以看到.Option。 BookingInfo 是一个数组。
如何设置此问题...我使用以下代码将json字符串反序列化为类对象
var AirTravelResultModel = JsonConvert.DeserializeObject<AirTravelResultModel>(xmlInputData);
答案 0 :(得分:5)
请看Camilo Martinez对此讨论的回答: Deserializing JSON when sometimes array and sometimes object
基本上,您需要将JsonConverter
属性添加到BookingInfo
媒体资源中,并在JsonConverter
实施中处理转化。
public class FlightOptionsList
{
public List<FlightOption> FlightOption { get; set; }
}
public class FlightOption
{
public string LegRef { get; set; }
public string Destination { get; set; }
public string Origin { get; set; }
public Option Option { get; set; }
}
public class Option
{
public string Key { get; set; }
public string TravelTime { get; set; }
[JsonConverter(typeof(SingleValueArrayConverter<BookingInfo>))]
public List<BookingInfo> BookingInfo { get; set; }
public Connection Connection { get; set; }
}
public class BookingInfo
{
public string BookingCode { get; set; }
public string BookingCount { get; set; }
public string CabinClass { get; set; }
public string FareInfoRef { get; set; }
public string SegmentRef { get; set; }
}
public class Connection
{
public string SegmentIndex { get; set; }
}
这是转换器:
public class SingleValueArrayConverter<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)
{
object retVal = new Object();
if (reader.TokenType == JsonToken.StartObject)
{
T instance = (T)serializer.Deserialize(reader, typeof(T));
retVal = new List<T>() { instance };
}
else if (reader.TokenType == JsonToken.StartArray)
{
retVal = serializer.Deserialize(reader, objectType);
}
return retVal;
}
public override bool CanConvert(Type objectType)
{
return true;
}
}
答案 1 :(得分:0)
本回答中的大多数文字都是来自您的问题的文字,并进行了一些调整。您需要做的就是修复您的JSON结构,并使用JsonProperty
属性修饰类,因为您的JSON属性名称中包含air:
,而C#中不允许:
。这就是全部。
第1步
首先需要修复的是你的JSON,因为在一种情况下air:BookingInfo
是一个对象,然后在另一种情况下,它是一个数组。因此,其架构不一致。正确的JSON就是这样的:
{
"air:FlightOption": [{
"LegRef": "hx5kk+3R2BKABGzqAAAAAA==",
"Destination": "LHE",
"Origin": "DXB",
"air:Option": {
"Key": "hx5kk+3R2BKA/FzqAAAAAA==",
"TravelTime": "P0DT3H0M0S",
"air:BookingInfo": [{
"BookingCode": "I",
"BookingCount": "7",
"CabinClass": "Economy",
"FareInfoRef": "hx5kk+3R2BKAzFzqAAAAAA==",
"SegmentRef": "hx5kk+3R2BKAtFzqAAAAAA=="
}]
}
},
{
"LegRef": "hx5kk+3R2BKAFGzqAAAAAA==",
"Destination": "DXB",
"Origin": "LHE",
"air:Option": {
"Key": "hx5kk+3R2BKACGzqAAAAAA==",
"TravelTime": "P0DT11H30M0S",
"air:BookingInfo": [{
"BookingCode": "U",
"BookingCount": "7",
"CabinClass": "Economy",
"FareInfoRef": "hx5kk+3R2BKA+FzqAAAAAA==",
"SegmentRef": "hx5kk+3R2BKAvFzqAAAAAA=="
},
{
"BookingCode": "Y",
"BookingCount": "9",
"CabinClass": "Economy",
"FareInfoRef": "hx5kk+3R2BKA+FzqAAAAAA==",
"SegmentRef": "hx5kk+3R2BKAxFzqAAAAAA=="
}
],
"air:Connection": {
"SegmentIndex": "0"
}
}
}
]
}
第2步
您可以使用Visual Studio轻松地为JSON创建类,如我在此answer中所示。
第3步
您需要稍微帮助序列化程序并告诉它如何将JSON属性映射到您的类的属性,为此您可以使用JsonPropertyAttribute
属性,如下所示:
public class FlightOptionsList
{
[JsonProperty("air:FlightOption")]
public AirFlightoption[] airFlightOption { get; set; }
}
public class AirFlightoption
{
public string LegRef { get; set; }
public string Destination { get; set; }
public string Origin { get; set; }
[JsonProperty("air:Option")]
public AirOption airOption { get; set; }
}
public class AirOption
{
public string Key { get; set; }
public string TravelTime { get; set; }
[JsonProperty("air:BookingInfo")]
public AirBookingInfo[] airBookingInfo { get; set; }
[JsonProperty("air:Connection")]
public AirConnection airConnection { get; set; }
}
public class AirBookingInfo
{
public string BookingCode { get; set; }
public string BookingCount { get; set; }
public string CabinClass { get; set; }
public string FareInfoRef { get; set; }
public string SegmentRef { get; set; }
}
public class AirConnection
{
public string SegmentIndex { get; set; }
}
第4步
您需要的唯一代码是:
var fol = JsonConvert.DeserializeObject<FlightOptionsList>("YourJSON");
答案 2 :(得分:0)
我很抱歉重复两次发布...不幸的是,这个问题在其前身Deserializing JSON when sometimes array and sometimes object中得到了解决。我不会使用您的对象。确保您的对象格式正确。有时,公司可能根据一个或多个对象将对象存储为数组或对象。您可能会遇到这种情况。确保您的转换器返回一个挂起对象类型的列表或数组。在我的实例中,我需要返回一个数组。
阐述Martinez和mfanto对Newtonsoft的回答。他们的答案确实适用于Newtonsoft:
这里是使用数组而不是列表(并正确命名)的示例。
public class SingleValueArrayConverter<T> : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartObject
|| reader.TokenType == JsonToken.String
|| reader.TokenType == JsonToken.Integer)
{
return new T[] { serializer.Deserialize<T>(reader) };
}
return serializer.Deserialize<T[]>(reader);
}
public override bool CanConvert(Type objectType)
{
return true;
}
}
然后在属性上写下:
[JsonProperty("INSURANCE")]
[JsonConverter(typeof(SingleValueArrayConverter<InsuranceInfo>))]
public InsuranceInfo[] InsuranceInfo { get; set; }
Newtonsoft将为您完成其余的工作。
return JsonConvert.DeserializeObject<T>(json);
为Martinez和mfanto喝彩!
信不信由你,这将与子项目一起使用。 (甚至可能必须这样做。)因此,在我的InsuranceInfo内,如果我有另一个对象/数组混合对象,请再次在该属性上使用它,如下所示:
[JsonProperty("CLAIM")]
[JsonConverter(typeof(SingleValueArrayConverter<Claim>))]
public Claim[] ClaimInfo { get; set; }
由于实现了WriteJson,因此还可以在必要时将对象重新序列化为json,但是到那时,它将始终是一个数组(是!)。