在 JSON.NET 数据解析期间忽略解析错误

Posted

技术标签:

【中文标题】在 JSON.NET 数据解析期间忽略解析错误【英文标题】:Ignore parsing errors during JSON.NET data parsing 【发布时间】:2014-11-24 07:17:33 【问题描述】:

我有一个具有预定义数据结构的对象:

public class A

    public string Id get;set;
    public bool? Enabled get;set;
    public int? Age get;set;

而 JSON 应该是

 "Id": "123", "Enabled": true, "Age": 23 

我想以积极的方式处理 JSON 错误,并且每当服务器为定义的数据类型返回意外值时,我希望它被忽略并设置默认值 (null)。

现在,当 JSON 部分无效时,我收到 JSON 阅读器异常:

 "Id": "123", "Enabled": "NotABoolValue", "Age": 23 

而且我根本没有得到任何东西。 我想要的是得到一个对象:

new A()  Id = "123", Enabled = null, Age = 23 

如果可能的话,解析警告。 用 JSON.NET 可以实现吗?

【问题讨论】:

【参考方案1】:

为了能够处理反序列化错误,请使用以下代码:

var a = JsonConvert.DeserializeObject<A>("-- JSON STRING --", new JsonSerializerSettings
    
        Error = HandleDeserializationError
    );

其中HandleDeserializationError是以下方法:

public void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)

    var currentError = errorArgs.ErrorContext.Error.Message;
    errorArgs.ErrorContext.Handled = true;

HandleDeserializationError 将被调用多次,因为 json 字符串中有错误。导致错误的属性不会被初始化。

【讨论】:

效果很好。这正是我想要的!谢谢 请注意,ErrorEventArgs 是 Newtonsoft.Json.Serialization.ErrorEventArgs 而不是 System.IO.ErrorEventArgs。 如何忽略集合中的单个错误元素?使用这种方法,Json.NET 似乎忽略了整个集合,而不仅仅是错误的元素。 根据我的经验,JSON.NET 只会在 json 字符串格式不正确的情况下忽略整个集合,如果 json 字符串格式正确但存在错误属性,它将忽略单个元素的错误属性类型不匹配。 (例如,您试图将字符串反序列化为整数属性) @IlijaDimov 很有趣。就我而言,元素的子树中某处缺少一个属性。但是,Json.NET 并没有在该位置引发错误,而是似乎在父集合处开始冒泡错误,如果我在那里执行 Handled = true,整个集合将设置为 null :/.【参考方案2】:

与 Ilija 的解决方案相同,但为懒惰/赶时间的人提供了一个单线器(归功于他)

var settings = new JsonSerializerSettings  Error = (se, ev) =>  ev.ErrorContext.Handled = true;  ;
JsonConvert.DeserializeObject<YourType>(yourJsonStringVariable, settings);

对 Jam 的支持使其更短 =)

【讨论】:

更短的Error = (se, ev) =&gt; ev.ErrorContext.Handled = true 不错!现在更新答案 =)【参考方案3】:

还有另一种方法。例如,如果您使用的是使用 newton json 并为您进行反序列化和序列化的 nuget 包。如果包没有处理错误,您可能会遇到此问题。那么你不能使用上面的解决方案。您需要在对象级别处理。这里变得 OnErrorAttribute 有用。因此,下面的代码将捕获任何属性的任何错误,您甚至可以在 OnError 函数中进行修改并分配默认值

public class PersonError

  private List<string> _roles;

  public string Name  get; set; 
  public int Age  get; set; 

  public List<string> Roles
  
    get
    
        if (_roles == null)
        
            throw new Exception("Roles not loaded!");
        

        return _roles;
    
    set  _roles = value; 
  

  public string Title  get; set; 

  [OnError]
  internal void OnError(StreamingContext context, ErrorContext errorContext)
  
    errorContext.Handled = true;
  

见https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm

【讨论】:

我试过这段代码,但尽管 'Handled=true',库还是抛出异常。错误?

以上是关于在 JSON.NET 数据解析期间忽略解析错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JSON.NET 使用十六进制编码字符解析格式错误的 JSONP?

如何修复使用 combine 解析 json 期间描述的错误?

使用 JSON.Net 解析某些数据

忽略解析错误 HTMLAgilityPack?

在 C# 中解析 JSON

如何忽略 JSON 解析回数据中的某些对象?