一、非标准 JSON 的常见问题与挑战
在实际开发场景中,我们常会遇到不符合严格 JSON 规范的数据源。这些数据可能包含注释、尾随逗号,甚至数值类型被错误地编码为字符串。例如以下包含注释和尾随逗号的 JSON 示例:
{
"temperatureCelsius": "25", // 注释示例:摄氏温度
"humidity": 60,
"windSpeed": 15, /* 多行注释
示例 */
"isRaining": false,
}
当使用默认的 System.Text.Json 解析器处理这类数据时,会抛出 JsonException 异常。这种情况常见于第三方 API 返回数据、人工维护的配置文件或历史遗留系统输出的 JSON 格式。
二、配置灵活解析选项
2.1 允许注释与尾随逗号
通过配置 JsonSerializerOptions 可增强解析器的容错能力。以下代码示例演示如何启用注释跳过和尾随逗号支持:
using System.Text.Json;
var options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true
};
string jsonData = File.ReadAllText("weather.json");
var weather = JsonSerializer.Deserialize<WeatherData>(jsonData, options);
- ReadCommentHandling:控制注释处理策略,支持 Skip(跳过注释)或 Allow(允许并保留注释)
- AllowTrailingCommas:启用对数组或对象末尾冗余逗号的容忍
2.2 数值类型自动转换
处理将数值存储为字符串的非标准做法时,可配置 NumberHandling 选项:
var options = new JsonSerializerOptions
{
NumberHandling = JsonNumberHandling.AllowReadingFromString |
JsonNumberHandling.WriteAsString
};
public class WeatherData
{
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public int TemperatureCelsius { get; set; }
}
该配置支持:
- AllowReadingFromString:自动将字符串格式的数值转换为目标类型
- WriteAsString:在序列化时将数值输出为字符串格式
三、完整解决方案实现
以下为处理复杂非标准 JSON 的完整示例:
using System.Text.Json;
using System.Text.Json.Serialization;
// 定义数据模型
public class WeatherData
{
[JsonPropertyName("temperatureCelsius")]
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public int Temperature { get; set; }
public decimal Humidity { get; set; }
}
// 配置解析选项
var options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString
};
try
{
string json = File.ReadAllText("nonStandardData.json");
var data = JsonSerializer.Deserialize<WeatherData>(json, options);
Console.WriteLine(#34;Temperature: {data.Temperature}°C");
}
catch (JsonException ex)
{
Console.WriteLine(#34;JSON 解析错误: {ex.Message}");
}
此实现能够正确处理以下类型的非标准 JSON:
{
/* 多行注释示例 */
"temperatureCelsius": "30", // 字符串格式数值
"humidity": 65.5, // 标准数值
"invalidField": "NaN", // 需要额外处理的特殊值
}
四、注意事项与最佳实践
- 安全性考量:启用宽松解析时需注意:
- 验证输入来源的可靠性
- 对反序列化后的数据进行完整性检查
- 避免将宽松配置用于敏感数据处理
- 性能优化:建议为高频解析操作创建静态选项实例:
private static readonly JsonSerializerOptions _options = new()
{
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true
};
- 版本兼容:JsonNumberHandling 等功能需要 .NET 5+ 版本支持,旧版本可采用自定义转换器方案。
通过合理配置 System.Text.Json 的序列化选项,开发者可以在保持严格类型安全的同时,灵活处理各种非标准 JSON 数据格式。建议根据具体场景选择适当的配置组合,在数据兼容性与系统安全性之间取得最佳平衡。