C#中如何输出对象内List<int>值并批量验证JSON导入数据
JSON导入数据的通用验证方案
问题背景
从JSON文件导入数据到C# Parameters 对象时,需要验证数据正确性,尤其是List类型的数值;由于对象属性多达100个且不统一,不想用大量switch语句,需要简洁的遍历验证方法。
现有代码与JSON示例
C#类与导入代码
// 修正原类定义的语法错误 public class Parameters { public List<int> ShortPeriodData { get; set; } public List<int> LongPeriodData { get; set; } public List<int> UponTriggerData { get; set; } public string LogRecordType { get; set; } public int? PowerVariance { get; set; } public List<double> BatteryData { get; set; } public List<int> MeanData { get; set; } public List<int> MeanVariance { get; set; } public int? PowerMean { get; set; } public string TriggerType { get; set; } } public static void Main() { string jsonFile = File.ReadAllText(path); var jsonResults = JsonConvert.DeserializeObject<List<Parameters>>(jsonFile); foreach (var result in jsonResults) { foreach (PropertyInfo prop in result.GetType().GetProperties()) { if (prop.GetValue(result, null) != null) { // 需要实现验证逻辑 } } } }
JSON示例
[ { "ShortPeriodData ":[0,0,0,0] }, { "LongPeriodData":[0,0,0,0], "UponTriggerData":[0,0,0,0], "LogRecordType":"Power" }, { "PowerVariance":5 }, { "BatteryData ":[0.7,0.3,1.4,5.7] }, { "MeanData":[65,71,81,89,98,95], "MeanVariance":[8,4,4,3,8,5], "PowerMean":64, "TriggerType":"PowerUp" } ]
解决方案
1. 修复JSON反序列化的键名问题
JSON中部分键带有多余空格(如"ShortPeriodData "),与类属性名不匹配会导致反序列化失败,可通过以下方式解决:
- 给类属性添加
[JsonProperty]特性,指定JSON中的键名(推荐,精准匹配):
public class Parameters { [JsonProperty("ShortPeriodData ")] public List<int> ShortPeriodData { get; set; } public List<int> LongPeriodData { get; set; } public List<int> UponTriggerData { get; set; } public string LogRecordType { get; set; } public int? PowerVariance { get; set; } [JsonProperty("BatteryData ")] public List<double> BatteryData { get; set; } public List<int> MeanData { get; set; } public List<int> MeanVariance { get; set; } public int? PowerMean { get; set; } public string TriggerType { get; set; } }
- 或配置Json.NET忽略未知成员(临时快速处理):
var settings = new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore }; var jsonResults = JsonConvert.DeserializeObject<List<Parameters>>(jsonFile, settings);
2. 通用反射验证逻辑
利用反射遍历所有属性,根据属性类型分支处理验证逻辑,避免大量switch语句。将不同类型的验证逻辑拆分为独立方法,便于扩展:
public static void ValidateParameter(Parameters param) { foreach (PropertyInfo prop in param.GetType().GetProperties()) { var value = prop.GetValue(param); if (value == null) continue; // 验证List<int>类型 if (prop.PropertyType == typeof(List<int>)) { ValidateIntList((List<int>)value, prop.Name); } // 验证List<double>类型 else if (prop.PropertyType == typeof(List<double>)) { ValidateDoubleList((List<double>)value, prop.Name); } // 验证可空int类型 else if (prop.PropertyType == typeof(int?)) { ValidateNullableInt((int?)value, prop.Name); } // 验证字符串类型 else if (prop.PropertyType == typeof(string)) { ValidateString((string)value, prop.Name); } // 其他类型可在此扩展 } } // 验证List<int>:示例检查非空、元素非负 private static void ValidateIntList(List<int> list, string propName) { if (list.Count == 0) { Console.WriteLine($"警告:{propName} 是空列表"); } foreach (var num in list) { if (num < 0) { Console.WriteLine($"错误:{propName} 包含无效负数 {num}"); } } } // 验证List<double>:示例检查非空、元素范围 private static void ValidateDoubleList(List<double> list, string propName) { if (list.Count == 0) { Console.WriteLine($"警告:{propName} 是空列表"); } foreach (var num in list) { if (num < 0 || num > 10) // 根据业务调整范围 { Console.WriteLine($"错误:{propName} 包含超出范围的值 {num}"); } } } // 验证可空int:示例检查非负 private static void ValidateNullableInt(int? value, string propName) { if (value < 0) { Console.WriteLine($"错误:{propName} 的值 {value} 为负数"); } } // 验证字符串:示例检查非空、枚举有效值 private static void ValidateString(string value, string propName) { if (string.IsNullOrWhiteSpace(value)) { Console.WriteLine($"警告:{propName} 是空字符串或空白"); } // 针对特定字符串属性的枚举验证 if (propName == nameof(Parameters.LogRecordType)) { var validTypes = new[] { "Power", "Battery" }; if (!validTypes.Contains(value)) { Console.WriteLine($"错误:{propName} 的值 {value} 不是有效类型"); } } else if (propName == nameof(Parameters.TriggerType)) { var validTypes = new[] { "PowerUp", "PowerDown" }; if (!validTypes.Contains(value)) { Console.WriteLine($"错误:{propName} 的值 {value} 不是有效类型"); } } }
3. 在主方法中调用验证
修改Main方法,添加验证调用:
public static void Main() { string jsonFile = File.ReadAllText(path); var settings = new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore }; var jsonResults = JsonConvert.DeserializeObject<List<Parameters>>(jsonFile, settings); foreach (var result in jsonResults) { ValidateParameter(result); } }
方案优势
- 无冗余代码:通过反射遍历属性,避免手写大量switch或if判断
- 扩展性强:新增属性时,只需在对应类型的验证方法中添加逻辑,或新增类型分支
- 逻辑清晰:不同类型的验证逻辑拆分到独立方法,便于维护和修改
内容的提问来源于stack exchange,提问作者new_to_coding
相关产品推荐
相关产品推荐

