asp.net-core - 从 Json.Net 中的 JsonReaderException 中查找无效值
问题描述
我正在运行下面的代码来故意抛出 JsonReaderException。它正确地给出了“无法将字符串转换为布尔值:aaa。路径‘活动’,第 3 行,位置 17”的异常消息。
有什么方法可以直接从 JsonReaderException 获取验证失败的值,所以我不必解析异常消息?
string json = @"{
'Email': 'james@example.com',
'Active': 'aaa',
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [
'User',
'Admin'
]
}";
try
{
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Email);
}
catch (JsonReaderException exc)
{
// Do Something
}
解决方案
看起来有问题的值没有保存为JsonReaderException
. 此值的唯一可能位置是Exception.Data
字典,但是 Json.NET 不会在此处添加任何内容。
但是,通过一些工作,您可以利用 Json.NET 的序列化错误事件处理功能在引发异常时直接访问错误值。首先,定义以下辅助方法和ErrorEventArgs
子类型:
public class ErrorAndValueEventArgs : Newtonsoft.Json.Serialization.ErrorEventArgs
{
public object ReaderValue { get; } = null;
public ErrorAndValueEventArgs(object readerValue, object currentObject, ErrorContext errorContext) : base(currentObject, errorContext)
{
this.ReaderValue = readerValue;
}
}
public static partial class JsonExtensions
{
public static TRootObject Deserialize<TRootObject>(string json, EventHandler<ErrorAndValueEventArgs> error, JsonSerializerSettings settings = null)
{
using (var sr = new StringReader(json))
using (var jsonReader = new JsonTextReader(sr))
{
var serializer = JsonSerializer.CreateDefault(settings);
serializer.Error += (o, e) => error(o, new ErrorAndValueEventArgs(jsonReader.Value, e.CurrentObject, e.ErrorContext));
return serializer.Deserialize<TRootObject>(jsonReader);
}
}
}
现在您将能够访问JsonReader.Value
抛出异常时的值:
object errorValue = null;
try
{
Account account = JsonExtensions.Deserialize<Account>(json, (o, e) => errorValue = e.ReaderValue);
Console.WriteLine(account.Email);
}
catch (JsonException exc)
{
// Do Something
Console.WriteLine("Value at time of {0} = {1}, Data.Count = {2}.", exc.GetType().Name, errorValue, exc.Data.Count);
// Prints Value at time of JsonReaderException = aaa, Data.Count = 0.
}
笔记:
由于您必须手动创建自己的
JsonTextReader
,因此您需要访问 JSON 字符串(或Stream
)才能使这种方法起作用。(这在您的问题中显示的示例中是正确的。)JsonSerializationException Parsing中显示了用于捕获附加错误信息的类似技术 。
你可能想增强
ErrorAndValueEventArgs
也记录JsonReader.TokenType
。如果在引发异常时读取器位于容器(对象或数组)的开头,JsonReader.Value
则将为 null。
演示小提琴在这里。
推荐阅读
- jquery - 如果我的 html 文件中有超过 1 个 select2,如何更改特定 select2 的宽度?
- javascript - 如果密钥名称未知,有没有办法访问 json 项目?
- spring-boot - 当我从 Test 调用方法时,我总是有 null resolte
- python - 一维和二维数组上的 numpy 点
- angular - Angular 共享组件在使用时引用旧视图
- jquery - 从 jquery 1.8.1 移动到 jquery 1.9.1 时出错
- java - ChronicleMap 中的“大小前缀 blob 就绪位设置为 NOT_COMPLETE”是什么意思?
- python - JSONDecodeError:期望用双引号括起来的属性名称:第 2 行第 6 列(字符 6)
- swift - 生成多页 PDF UIView
- assembly - 如何从程序集引导加载程序与 x86 I/O 设备交互?