【问题标题】:Exception message change in latest version最新版本中的异常消息更改
【发布时间】:2014-01-03 15:23:27
【问题描述】:

我刚刚将 Newtonsoft.Json 库从 4.5.1 更新到 5.0.8。我注意到其中一条异常消息发生了变化。一旦无法反序列化该值,我的 400 响应中将包含以下内容,“错误转换值...”。现在,此消息在 4.5.1 中有所不同。版本的库。问题是对象的全名被暴露了,这对我来说是一种不受欢迎的行为。

为了澄清:

问题如下。直到 Newtonsoft.Json 库的 4.5.1 版本,一旦抛出 JsonSerializationException,响应中的消息只是指出某个对象无法被序列化。从那个版本开始,响应消息中的库,是的,它包括错误消息,还包括它未能序列化到的对象的全名。很遗憾,因为我不想将错误消息中的命名空间暴露给外界。

我刚刚检查了JSON库的源代码,我发现StringEnumConverter中的代码现在是:

catch (Exception ex)
{
    throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(reader.Value), objectType), ex);
}

同时,它抛出默认的Enum.Parse ArgumentException 并显示消息“必须指定有效信息以解析字符串”。之前。

现在,我更喜欢这条消息,因为它没有向用户显示我的 API 的内部命名空间。

我试图在我的 Application_Start 方法中连接事件 JsonFormatter.SerializerSettings.Error,但是我无法执行我想要执行的操作。 我有机会访问我要处理的异常,

private static void Error(object sender, ErrorEventArgs errorEventArgs)
{
    if (errorEventArgs.ErrorContext.Error.GetType() == typeof(JsonSerializationException))
    {

但是所有属性都是只读的,我想修改的对象都被标记为内部的。重新抛出异常也不例外。

为清楚起见,请查看 Newtonsoft.Json.Net40 项目中的 StringEnumConverterJsonSerializerInternalBase 类。

您知道在哪里挂钩有问题的库以覆盖错误消息吗?或者关于如何解决问题的任何其他想法(停止在错误消息中显示完整的命名空间)?

我的问题是,我能否以某种方式重新抛出异常并指定不同的消息,比如 4.5.1 中的消息?

【问题讨论】:

    标签: c# json.net asp.net-web-api


    【解决方案1】:

    过了一会儿,我找到了一个可行的解决方案。我基本上创建了一个从 StringEnumConverter 派生的新转换器并覆盖了 ReadJson 方法。

    我的新转换器如下所示:

    public class StringEnumConverterEx : StringEnumConverter
        {
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                // the message in the response, once an serialization exception is thrown, after the version 4.5.1 of Newtonsoft.JSON library,
                // has changed. As we do not want to expose the full namespace of our Enums, we are catching the exception and re-throwing it
                // with a different message.
                try
                {
                    return base.ReadJson(reader, objectType, existingValue, serializer);
                }
                catch (JsonSerializationException)
                {
                    string values = objectType.IsEnum ? String.Join(",", Enum.GetNames(objectType)) : string.Empty;
    
                    throw new JsonSerializationException(string.Format("Error converting value {0}, possible values are: {1}",
                        objectType.Name, values));
                }
            }
        }
    

    现在我只是在我的应用启动时添加这个转换器而不是原来的 StringEnumConverter。

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverterEx());
    

    这可以解决问题并覆盖异常消息。 如您所见,我还在消息中提供了该 Enum 的可能值。

    希望这对其他人有帮助。

    干杯

    【讨论】:

      【解决方案2】:

      必须在字符串中指定解析的有效信息

      就异常消息而言,这是一个非常糟糕的消息。它完全没有人类解决问题所需的任何信息。这就是所需要的,必须更改软件才能真正解决问题。要么需要修复错误,要么需要改进数据验证。新的异常消息是一个很大的改进,它告诉您从哪里开始查找。

      您仍然可以隐藏自己,仅当 InnerException 不为 null 时才显示它。比如:

        private static void Error(object sender, ErrorEventArgs errorEventArgs)
        {
            var ex = errorEventArgs.ErrorContext.Error;
            if (ex.GetType() == typeof(JsonSerializationException)) {
               if (ex.InnerException != null) ex = ex.InnerException();
               Console.WriteLine(ex.Message);
            // etc...
      

      【讨论】:

      • 没问题,但是在哪里呢?我在 jsonFormatter.SerializerSettings.Error 上尝试了一个委托,而不是使用 ErrorEventArgs,但没有成功。如果我尝试类似 if (errorEventArgs.ErrorContext.Error.GetType() == typeof(Newtonsoft.Json.JsonSerializationException)) { throw new... } 我得到“当前错误上下文错误与请求的错误不同。”响应正文中的消息。关于在哪里拦截它以及如何改变它的任何想法?谢谢
      • 您在向我询问有关我看不到的代码的详细信息。把它放在你最初报告错误的地方。
      • 我刚刚更新了我的问题。任何提示都将受到欢迎!谢谢
      • 我不明白挂断可能是什么。将 sn-p 更新为更像您的错误事件处理程序。您需要在问题中发布更多代码。
      【解决方案3】:

      :edit: 没注意到你问过 web.api

      控制返回的错误消息的一种方法是抛出HttpResponseException,而不是不处理异常。更多信息可以在this blog 中找到,例如

      另一种方法是实现自定义操作过滤并将异常重定向到默认错误页面或执行任何操作。详细例子可以found here

      【讨论】:

      • 这不是一个 mvc 应用程序。这是来自我的 web api 项目的 400 响应,其中详细说明了响应数据中出了什么问题。
      猜你喜欢
      • 1970-01-01
      • 2014-01-22
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多