C# .NET将MySQL读取的JSON字符串反序列化映射到billItems结构体
现有实现的核心硬伤
- 字符串处理逻辑完全错位:原本通过Newtonsoft.Json反序列化得到结构化的JSON对象后,代码强行将对象转成字符串、去掉首尾大括号、按逗号切分片段,本质是把结构化数据拆成了无意义的字符串碎片,完全无法对应到
billItems的字段结构 - 循环逻辑存在严重漏洞:
JsonConversion方法的return语句写在foreach循环内部,第一次遍历明细元素就直接退出方法,根本无法处理单条账单下的所有明细- 用于存明细的
details集合在账单循环外部初始化,处理新账单时没有清空集合,会把不同账单的明细混在一起
- 类型定义匹配偏差:
bill和billItems结构体里使用无类型的ArrayList存集合数据,赋值后无法获得强类型的明细对象,后续读取明细字段需要反复做类型转换,还容易出错 - 冗余的正则替换逻辑:强行移除字符串里的空格、换行,会破坏带空格的商品名等有效字段值,本身对JSON反序列化没有任何帮助
落地修正方案
步骤1:调整结构体定义,匹配JSON结构
先对应JSON里的嵌套tax对象定义强类型,把原有的无类型ArrayList替换为明确元素类型的集合,保证字段和JSON key一一对应:
// 匹配JSON中嵌套的tax明细结构 public struct TaxInfo { public string name; public double price; public int quantity; public double percent; public double amount; public ArrayList contents; } public struct billItems { public int id; public int item; public int quantity; public string name; public double price; // 替换原ArrayList类型的tax为强类型,匹配JSON结构 public TaxInfo tax; public double discount; } public struct bill { public int id; public DateTime docdate; // 替换原无类型ArrayList为存billItems的泛型集合 public List<billItems> billDetails; }
步骤2:重写JSON转换逻辑
完全移除手动拆字符串、去括号的冗余代码,直接利用Newtonsoft.Json的类型映射能力完成反序列化,不需要手动处理字段格式:
private List<billItems> JsonConversion(string jsonContent) { // 直接将JSON字符串反序列化为billItems集合,自动完成字段值匹配 return JsonConvert.DeserializeObject<List<billItems>>(jsonContent); }
步骤3:修正读取逻辑的循环漏洞
移除跨账单复用的集合变量,每条账单重新实例化独立的对象,避免数据串扰:
public ArrayList ReadBill(MySqlConnection connection) { ArrayList billList = new ArrayList(); string query = "SELECT id,DATE_FORMAT(DATE, \"%d-%m-%Y\")docdate,contents FROM bills WHERE progress='Paid'; "; using (MySqlCommand cmd = new MySqlCommand(query, connection)) { DataTable dt = new DataTable(); dt.Load(cmd.ExecuteReader()); for (int i = 0; i < dt.Rows.Count; i++) { // 每条账单循环内重新实例化bill对象,避免跨账单数据污染 bill currentBill = new bill(); currentBill.id = Convert.ToInt32(dt.Rows[i]["id"]); currentBill.docdate = Convert.ToDateTime(dt.Rows[i]["docdate"]); // 直接反序列化拿到强类型明细集合赋值 currentBill.billDetails = JsonConversion(dt.Rows[i]["contents"].ToString()); billList.Add(currentBill); } } return billList; }
修正后的运行效果
- 反序列化过程自动匹配字段:就算JSON中的
price是字符串形式的数值(如"50.000"),也会自动转换为目标结构体的double类型,不需要手动做字符串解析 - 商品名中的空格、特殊字符会被完整保留,不会被正则替换逻辑破坏
- 彻底解决原代码中提前返回、集合复用导致的逻辑bug,每条账单的明细数据独立完整
内容的提问来源于stack exchange,提问作者Mousmi
相关产品推荐
相关产品推荐

