我有一个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]),或者更改反序列化的类型,使其成为可以从JSON对象反序列化的普通.NET类型(例如,不是像integer这样的基元类型,也不是像array或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);
看看Camilo Martinez对此讨论的回答:当有时数组,有时对象时反序列化JSON
基本上,您需要将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;
}
}
这个答案中的大部分文本都是经过一些调整后的问题文本。您所需要做的就是修复您的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
您可以使用VisualStudio轻松地为JSON创建类,如我在这个答案中所示。
步骤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");
我很抱歉重复发布了两次。。。不幸的是,这个问题在其前身中得到了一定程度的解决:当有时是数组,有时是对象时,反序列化JSON。我不会使用你的物品。确保你的物品成型良好。有时,公司可能会将对象存储为数组或对象,具体取决于是否有一个或多个。你可能会遇到这种情况。请确保转换器正在返回挂起对象类型的列表或数组。在我的例子中,我需要返回一个数组。
阐述马丁内斯和孟山都对纽顿软的回答。他们的答案确实适用于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);
为马丁内斯和mfanto干杯!
信不信由你,这将适用于子项目。(它甚至可能不得不这样做。)所以…在我的InsuranceInfo中,如果我有另一个对象/数组混合,请在该属性上再次使用它,如下所示:
[JsonProperty("CLAIM")]
[JsonConverter(typeof(SingleValueArrayConverter<Claim>))]
public Claim[] ClaimInfo { get; set; }
由于实现了WriteJson,这也将允许在必要时将对象保留回json,但此时,它将始终是一个数组(yay!)。