ASP.NET读取JSON文件映射实体类无值问题求助
酒店预订JSON数据映射到实体类问题解决指导
我有一个酒店预订JSON文件,已经创建了对应的实体类,想要把JSON数据保存到类的属性中,但当前编写的读取代码无法获取到任何值,求指导如何正确读取所有JSON节点并完成数据映射。
JSON内容
{"header": {"hid": "95845-5bhj-j908-o987-hhg5665","datestamp": "2024-01-21"},"body": [{"hotelbooking": [{"Customer": {"Bookings": {"Profile": {"name": "Test","dob": "1989-01-01","mobile": "+919999999999","address": "C-366,Saket,Delhi,INDIA,110044","email": "test@gmail.com","id": "GH2673677"},"roomtype": "DELUXE POOL VIEW"}},"BookingStatus": {"Confirm": {"amount": 4800},"Pax": "4","currency": "THB","bookDateTime": "2024-01-21T21:10:54Z","address": "PATONG","days": "4","paymentstatus": "CONFIRM"},"RoomDetails": {"Rooms": [{"roomtype": "DELUXE GARDEN VIEW","pricepernight": 1000,"currency": "THB","refid": "0032514569"},{"roomtype": "DELUXE POOL VIEW","pricepernight": 1200,"currency": "THB","refid": "0069584214"},{"roomtype": "DELUXE SEA VIEW","pricepernight": 1300,"currency": "THB","refid": "0098541239"},{"roomtype": "SUITE POOL VIEW","pricepernight": 2000,"currency": "THB","refid": "0036521456"},{"roomtype": "SUITE POOL ACCESS","pricepernight": 3000,"currency": "THB","refid": "002651425"},{"roomtype": "PRESEDENTIAL SUITE INFINITY POOL","pricepernight": 6000,"currency": "THB","refid": "006985321"}],"bookstartDate": "2024-04-09","bookendDate": "2024-04-13"},"paymentmode": "cc","creditcardNumber": "XXXXXXXXXXXX8976","paymentRef": "bhgd73838-jdf73738"}],"customerId": "yryu78876","paymentbank": "DBS Bank","secdeposit": "No","OtherInfo": [{"ExtraBed": "No","Breakfast": "Yes","RefNo": "0069584214"}]}]}
实体类代码
public class Body { public List<Hotelbooking> hotelbooking { get; set; } public string customerId { get; set; } public string paymentbank { get; set; } public string secdeposit { get; set; } public List<OtherInfo> OtherInfo { get; set; } } public class Bookings { public Profile Profile { get; set; } public string roomtype { get; set; } } public class BookingStatus { public Confirm Confirm { get; set; } public string Pax { get; set; } public string currency { get; set; } public DateTime bookDateTime { get; set; } public string address { get; set; } public string days { get; set; } public string paymentstatus { get; set; } } public class Confirm { public int amount { get; set; } } public class Customer { public Bookings Bookings { get; set; } } public class Header { public string hid { get; set; } public string datestamp { get; set; } } public class Hotelbooking { public Customer Customer { get; set; } public BookingStatus BookingStatus { get; set; } public RoomDetails RoomDetails { get; set; } public string paymentmode { get; set; } public string creditcardNumber { get; set; } public string paymentRef { get; set; } } public class OtherInfo { public string ExtraBed { get; set; } public string Breakfast { get; set; } public string RefNo { get; set; } } public class Profile { public string name { get; set; } public string dob { get; set; } public string mobile { get; set; } public string address { get; set; } public string email { get; set; } public string id { get; set; } } public class Room { public string roomtype { get; set; } public int pricepernight { get; set; } public string currency { get; set; } public string refid { get; set; } } public class RoomDetails { public List<Room> Rooms { get; set; } public string bookstartDate { get; set; } public string bookendDate { get; set; } }
现有读取代码
string jsonFile = @"E:\hotel.json"; var json = File.ReadAllText(jsonFile); var jsonObject = JObject.Parse(json); JArray hotelbodyArrary = (JArray)jsonObject["body"]; if (hotelbodyArrary != null) { Body body = new Body(); Hotelbooking ho = new Hotelbooking(); foreach (var item in hotelbodyArrary) { ho.paymentmode = Convert.ToString(item["paymentmode"]); ho.creditcardNumber = Convert.ToString(item["creditcardNumber"]); } }
问题分析与解决方案
问题根源
现有代码取不到值的核心原因是节点路径错误:
body数组里的每个元素是Body类型对象,而paymentmode、creditcardNumber这些字段属于Body对象下的hotelbooking数组中的Hotelbooking对象,并非直接在body元素下,所以item["paymentmode"]自然返回null。- 手动逐层解析JSON不仅繁琐,还容易遗漏层级,出错概率高。
最优解决方案:用JSON序列化库自动映射
直接借助成熟的JSON序列化库(比如Newtonsoft.Json或System.Text.Json)完成自动映射,无需手动解析每个节点,高效且不易出错。
第一步:补充根实体类
JSON最外层包含header和body两个节点,需要新增一个根类来对应:
public class HotelBookingRoot { public Header header { get; set; } public List<Body> body { get; set; } }
第二步:用Newtonsoft.Json实现映射
如果项目中使用Newtonsoft.Json(Json.NET),代码如下:
using Newtonsoft.Json; using System.IO; string jsonFile = @"E:\hotel.json"; var jsonContent = File.ReadAllText(jsonFile); // 一键反序列化到根对象 var hotelData = JsonConvert.DeserializeObject<HotelBookingRoot>(jsonContent); // 示例:访问映射后的数据 if (hotelData?.body != null && hotelData.body.Count > 0) { var firstBody = hotelData.body[0]; Console.WriteLine($"客户ID:{firstBody.customerId}"); if (firstBody.hotelbooking != null && firstBody.hotelbooking.Count > 0) { var firstBooking = firstBody.hotelbooking[0]; Console.WriteLine($"支付方式:{firstBooking.paymentmode}"); Console.WriteLine($"客户姓名:{firstBooking.Customer.Bookings.Profile.name}"); } }
第三步:用System.Text.Json实现映射(.NET Core/.NET 5+)
如果使用.NET自带的System.Text.Json,代码如下:
using System.Text.Json; using System.IO; string jsonFile = @"E:\hotel.json"; var jsonContent = File.ReadAllText(jsonFile); // 一键反序列化到根对象 var hotelData = JsonSerializer.Deserialize<HotelBookingRoot>(jsonContent); // 示例:访问映射后的数据 if (hotelData?.body != null && hotelData.body.Count > 0) { var firstBody = hotelData.body[0]; Console.WriteLine($"客户ID:{firstBody.customerId}"); if (firstBody.hotelbooking != null && firstBody.hotelbooking.Count > 0) { var firstBooking = firstBody.hotelbooking[0]; Console.WriteLine($"支付方式:{firstBooking.paymentmode}"); Console.WriteLine($"客户姓名:{firstBooking.Customer.Bookings.Profile.name}"); } }
注意事项
- 确保实体类的属性名称和JSON节点名称完全一致(大小写敏感,除非配置序列化选项忽略大小写)。
- 如果使用System.Text.Json,对于
DateTime类型的bookDateTime,默认可以正确解析ISO格式的时间字符串,无需额外配置。
内容的提问来源于stack exchange,提问作者Rahul Aggarwal
相关产品推荐
相关产品推荐

