我需要处理JSON文件,该文件可能包含JSON数组中不同数量的项目。目前我正在使用这样的代码:
var obj = JArray.Parse(File.ReadAllText(url));
dfd = (from a in obj
where
a["PriceItems"][0]["CityFromID"].Value<string>() == cityfromcode &&
a["PriceItems"][0]["CityToID"].Value<string>() == citytocode &&
a["PriceItems"][0]["AirlineCode"].Value<string>() == airlinecode
select new PricesViewModel.DepartureFlightsData
{
DepartureCity = a["PriceItems"][0]["CityFromName"].Value<string>(),
DepartureAirport = a["PriceItems"][0]["AirportFromCode"].Value<string>(),
DepartureDate = depDate,
DepartureTime = a["PriceItems"][0]["DepartureTime"].Value<string>(),
DepartureAirline = a["PriceItems"][0]["AirlineCode"].Value<string>(),
DepartureFlight = a["PriceItems"][0]["FlightNumber"].Value<string>(),
DepartureFlightId = a["PriceItems"][0]["FlightID"].Value<string>(),
Price = a["PriceItems"][0]["Price"].Value<int>(),
Currency = a["PriceItems"][0]["Currency"].Value<string>()
}).FirstOrDefault();
但是此代码仅对特定索引处的项目有效,我应该如何更改此代码以能够在某个特定位置处理项目,与 [0] 不同?
JSON 可能会因此而改变:
[
{
"PriceItems": [
{
"FlightID": "567",
"FlightNumber": "001",
"CityFromID": "1",
"CityFromCode": "MOW",
"CityToID": "539",
"CityToCode": "",
"AirportFromCode": "DME",
"AirportFromName": null,
"AirportToCode": "VRN",
"AirportToName": null,
"DepartureDate": "20150318",
"DepartureTime": "10:00",
"ArrivalDate": "20150318",
"ArrivalTime": "12:00",
"Price": 300,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "aerobus A-310",
"AirlineName": "Сан Экспресс",
"AirlineCode": "00",
"PackageID": "232",
"CityFromName": "Москва",
"CityToName": "ВАРНА"
},
{
"FlightID": "568",
"FlightNumber": "002",
"CityFromID": "539",
"CityFromCode": null,
"CityToID": "1",
"CityToCode": null,
"AirportFromCode": "VRN",
"AirportFromName": null,
"AirportToCode": "DME",
"AirportToName": null,
"DepartureDate": "20150319",
"DepartureTime": "12:00",
"ArrivalDate": "20150319",
"ArrivalTime": "14:00",
"Price": 300,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "aerobus A-310",
"AirlineName": "Сан Экспресс",
"AirlineCode": "00",
"PackageID": "232",
"CityFromName": "ВАРНА",
"CityToName": "Москва"
}
],
"VariantItems": [
{
"FlightID": "567",
"FlightBackID": "568"
}
],
"Error": null
},
{
"PriceItems": [
{
"FlightID": "569",
"FlightNumber": "546",
"CityFromID": "1",
"CityFromCode": "MOW",
"CityToID": "559",
"CityToCode": "",
"AirportFromCode": "DME",
"AirportFromName": null,
"AirportToCode": "SFA",
"AirportToName": null,
"DepartureDate": "20150318",
"DepartureTime": "08:00",
"ArrivalDate": "20150318",
"ArrivalTime": "10:00",
"Price": 200,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "Boeing",
"AirlineName": "BRITISH AIRWAYS",
"AirlineCode": "BA",
"PackageID": "232",
"CityFromName": "Москва",
"CityToName": "СОФИЯ"
},
{
"FlightID": "571",
"FlightNumber": "547",
"CityFromID": "559",
"CityFromCode": null,
"CityToID": "1",
"CityToCode": null,
"AirportFromCode": "SFA",
"AirportFromName": null,
"AirportToCode": "DME",
"AirportToName": null,
"DepartureDate": "20150319",
"DepartureTime": "18:00",
"ArrivalDate": "20150319",
"ArrivalTime": "20:00",
"Price": 185,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "Boeing",
"AirlineName": "BRITISH AIRWAYS",
"AirlineCode": "BA",
"PackageID": "232",
"CityFromName": "СОФИЯ",
"CityToName": "Москва"
}
],
"VariantItems": [
{
"FlightID": "569",
"FlightBackID": "571"
}
],
"Error": null
}
]
到那个:
[
{
"PriceItems": [
{
"FlightID": "565",
"FlightNumber": "731",
"CityFromID": "1",
"CityFromCode": "MOW",
"CityToID": "19",
"CityToCode": "BCN",
"AirportFromCode": "DME",
"AirportFromName": null,
"AirportToCode": "BCN",
"AirportToName": null,
"DepartureDate": "20150318",
"DepartureTime": "17:00",
"ArrivalDate": "20150318",
"ArrivalTime": "21:00",
"Price": 350,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "Boeing",
"AirlineName": "TRANSAERO",
"AirlineCode": "UN",
"PackageID": "232",
"CityFromName": "Москва",
"CityToName": "Барселона"
},
{
"FlightID": "563",
"FlightNumber": "2639",
"CityFromID": "1",
"CityFromCode": "MOW",
"CityToID": "19",
"CityToCode": "BCN",
"AirportFromCode": "SVO",
"AirportFromName": null,
"AirportToCode": "BCN",
"AirportToName": null,
"DepartureDate": "20150318",
"DepartureTime": "11:50",
"ArrivalDate": "20150318",
"ArrivalTime": "19:15",
"Price": 350,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "Boeing",
"AirlineName": "Aeroflot-Russian International AirLines",
"AirlineCode": "SU",
"PackageID": "232",
"CityFromName": "Москва",
"CityToName": "Барселона"
},
{
"FlightID": "566",
"FlightNumber": "732",
"CityFromID": "19",
"CityFromCode": null,
"CityToID": "1",
"CityToCode": null,
"AirportFromCode": "BCN",
"AirportFromName": null,
"AirportToCode": "DME",
"AirportToName": null,
"DepartureDate": "20150319",
"DepartureTime": "07:00",
"ArrivalDate": "20150319",
"ArrivalTime": "11:00",
"Price": 350,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "Boeing",
"AirlineName": "TRANSAERO",
"AirlineCode": "UN",
"PackageID": "232",
"CityFromName": "Барселона",
"CityToName": "Москва"
},
{
"FlightID": "564",
"FlightNumber": "2640",
"CityFromID": "19",
"CityFromCode": null,
"CityToID": "1",
"CityToCode": null,
"AirportFromCode": "BCN",
"AirportFromName": null,
"AirportToCode": "SVO",
"AirportToName": null,
"DepartureDate": "20150319",
"DepartureTime": "11:50",
"ArrivalDate": "20150319",
"ArrivalTime": "14:50",
"Price": 350,
"Currency": "€",
"AirServiceID": "89",
"AirCraft": "Boeing",
"AirlineName": "Aeroflot-Russian International AirLines",
"AirlineCode": "SU",
"PackageID": "232",
"CityFromName": "Барселона",
"CityToName": "Москва"
}
],
"VariantItems": [
{
"FlightID": "563",
"FlightBackID": "566"
},
{
"FlightID": "565",
"FlightBackID": "566"
},
{
"FlightID": "563",
"FlightBackID": "564"
},
{
"FlightID": "565",
"FlightBackID": "564"
}
],
"Error": null
}
]
据我了解,您希望首先收到"PriceItems"对象。可以使用 SelectMany() LINQ 扩展方法。该方法将完全按照您的要求执行:
var obj = JArray.Parse(File.ReadAllText(url));
dfd = obj.SelectMany(x => x["PriceItems"])
.Select(a => new PricesViewModel.DepartureFlightsData {
DepartureCity = a["CityFromName"].Value<string>(),
DepartureAirport = a["AirportFromCode"].Value<string>(),
DepartureDate = depDate,
DepartureTime = a["DepartureTime"].Value<string>(),
DepartureAirline = a["AirlineCode"].Value<string>(),
DepartureFlight = a["FlightNumber"].Value<string>(),
DepartureFlightId = a["FlightID"].Value<string>(),
Price = a["Price"].Value<int>(),
Currency = a["Currency"].Value<string>()
}).FirstOrDefault();
这是一个更简单的替代方案。
public class VarientItemsPlaceHolder
{
public string FlightID;
public string FlightBackID;
}
public class OuterJsonObject
{
public List<PricesViewModel.DepartureFlightsData> PriceItems;
public List<VarientItemsPlaceHolder> VarientItems;
public strint Error;
}
// deserialize the whole thing first
List<OuterJsonObject> everything = JsonConvert.DeserializeObject<OuterJsonObject>(File.ReadAllText(url));
// flatten the Lists of PricesViewModel.DepartureFlightsData into one master List<PricesViewModel.DepartureFlightsData>
List<PricesViewModel.DepartureFlightsData> allFlights = everything.SelectMany(x => x.PricedItems).ToList();
// filter the master list using cityfromcode, citytocode, airlinecode
List<PricesViewModel.DepartureFlightsData> filteredFlights = allFlights.Where(x => x.CityFromID == cityfromcode && x.CityToID == citytocode && x.AirlineCode == airlinecode).ToList();
请注意,您不必像我一样打破这一点。代码可以通过编写其中一些 LINQ 查询来压缩,我只是选择逐步完成,因为它使数据处理更加清晰。
正如其他人指出的那样,关键是使用 SelectMany
方法来聚合包含该列表的每个对象中的所有PricedItems
。我个人更喜欢使用静态类型。在转换为模型类型之前,您正在使用JArray
作为中介,这可以继续,并且您可能已经在某处的模型中定义了我在这里定义的类型,因此不要使用我的类定义,我只是将它们放在那里以明确它是如何工作的。json 等效于我的 OuterJsonObject
类型,在我反序列化为该类型之后,我只需一两个 LINQ 查询即可获得所需的筛选列表。