我刚刚将Newtonsoft.Json库从4.5.1更新到5.0.8。我注意到的是其中一条异常消息发生了变化。一旦该值无法反序列化,我的400响应“错误转换值...”中包含以下内容。现在,这条消息在4.5.1中有所不同。 lib的版本。问题是对象的全名是暴露的,这对我来说是一种不良行为。
为了澄清:
问题如下。直到Newtonsoft.Json库的4.5.1版本,抛出JsonSerializationException后,响应中的消息才指定某个对象无法序列化。从该版本开始,响应消息中的库,是的,它包括错误消息,但也包括它无法序列化的对象的全名。遗憾的是,我不想将错误消息中的命名空间暴露给外界。
我只是检查JSON lib的源代码,我发现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项目中的StringEnumConverter
和JsonSerializerInternalBase
类。
您是否知道在哪里挂钩有问题的库以覆盖错误消息?或者关于如何解决问题的任何其他想法(停止在错误消息中显示完整的命名空间)?
我的问题是,我可以以某种方式重新抛出一个异常,指定一个不同的消息,就像4.5.1中的那个消息一样吗?
答案 0 :(得分:4)
过了一会儿,我找到了一个有效的解决方案。我基本上创建了一个从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());
这样做可以解决异常消息。 正如您所看到的,我还在消息中提供了该枚举的可能值。
希望这会帮助别人。
干杯
答案 1 :(得分:2)
必须指定用于在字符串
中解析的有效信息
就异常消息而言,这是一个非常悲惨的消息。它完全没有人类解决问题所需的任何信息。这就是所需要的,必须改变软件才能真正解决问题。要么需要修复bug,要么需要改进数据验证。新的异常消息是一个很大的改进,它告诉你从哪里开始寻找。
您仍然可以隐藏自己,只显示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...
答案 2 :(得分:0)
:编辑:没有注意到你问过web.api
控制返回的错误消息的一种方法是抛出HttpResponseException
而不是保留未处理的异常。有关详细信息,请参阅this blog,例如
另一种方法是实现自定义操作过滤并将异常重定向到默认错误页面或执行任何操作。详细示例可以是found here