【问题标题】:Proper way to rethrow a JsonConverter exception重新抛出 JsonConverter 异常的正确方法
【发布时间】:2021-12-27 02:58:03
【问题描述】:

我有以下设置用于反序列化一些 json:

parsedResponse = JsonConvert.DeserializeObject<T>(
  json,
  new JsonSerializerSettings
  {
    Error = (object sender, ErrorEventArgs args) =>
    {
      throw new MyParseException($"Parse error: {args.ErrorContext.Error.Message}");
    },
    Converters =
    {
      new MyItemConverter(),
      new BoolConverter(),
      new UnixDateTimeConverter(),
      new NullableIntConverter(),
      new UriConverter()
    }
  }
);

在一种情况下,json 有一堆空值(如"title" : null, 等),这会在我的一个转换器中导致 NullReferenceException。但是在错误处理程序中抛出 MyParseException 会导致

System.InvalidOperationException:当前错误上下文错误与请求错误不同。

我想我可以这样做:

try
{
    parsedResponse = JsonConvert.DeserializeObject<T>(
      json,
      new JsonSerializerSettings
      {
        Converters =
        {
          new MyItemConverter(),
          new BoolConverter(),
          new UnixDateTimeConverter(),
          new NullableIntConverter(),
          new UriConverter()
        }
      }
    );
}
catch (Exception ex)
{
    throw new MyParseException($"Parse error: {ex.Message}");
}

但是有更好的方法吗? (也许更类似于我的原始解决方案,不会导致错误上下文问题?)

【问题讨论】:

  • 错误处理让您可以捕获错误并选择是处理它并继续序列化还是让错误冒泡并在您的应用程序中抛出。 (Source)所以基本上它说你应该根据你的情况使用这个处理程序来设置args.ErrorContext.Handled 的值。根据我的理解,它不是为您的用例设计的。
  • 如您所见,ErrorContext's Error 只有一个 getter 而没有 setter。
  • 不幸的是,设置args.ErrorContext.Handled = true; 并在错误处理程序中抛出异常仍然会导致“错误上下文错误与请求的错误不同”异常最终被抛出。我会看看我是否可以多花点时间,但 try-catch 方法可能是唯一的解决方案
  • 也许我的措辞不清楚。 Error 事件处理程序不是引发异常的适当位置。
  • 感谢您的提示(我不了解 EDI)。我使用了您链接的第一个 Newtonsoft 页面上的示例 - 在列表中捕获错误,然后在 DeserializeObject 块之后重新抛出 AggregateException(如果列表不为空)

标签: c# json parsing json.net jsonconvert


【解决方案1】:

基于 Newtonsoft 示例 here。我最终做了以下事情:

List<MyParseException> errors = new List<MyParseException>();

T parsedResponse = JsonConvert.DeserializeObject<T>(
  json,
  new JsonSerializerSettings
  {
    Error = (object sender, ErrorEventArgs args) =>
    {
      errors.Add(new MyParseException(String.Format("Parse error: {0}", args.ErrorContext.Error.Message), args.ErrorContext.Error));
      args.ErrorContext.Handled = true;
    },
    Converters =
    {
      new MyItemConverter(),
      new BoolConverter(),
      new UnixDateTimeConverter(),
      new NullableIntConverter(),
      new UriConverter()
    }
  }
);

if (errors.Count == 1)
{
  MyParseException firstException = errors[0];
  firstException.Data["json"] = json;
  throw firstException;
}
else if (errors.Count > 1)
{
  AggregateException ex = new AggregateException("Unable to parse json. See innner exceptions and exception.Data[\"json\"] for details", errors);
  ex.Data["json"] = json;
  throw ex;
}

【讨论】:

    猜你喜欢
    • 2015-04-29
    • 1970-01-01
    • 2019-05-04
    • 2011-07-28
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多