在尝试对某些代码进行故障排除时,我查看了捕获任何未处理的异常的日志。
在我的日志功能中,我有以下代码行:
data = JsonConvert.DeserializeObject(exception)
数据值的一部分读取为\“ Message \”:null。当我调试并查看异常时,异常的Message属性具有一个值(该值准确地描述了问题)。如果我尝试使用上面的行将其他异常转换为JSON,则会在生成的JSON中看到Message属性的值。
我想念什么?
这看起来像中的错误AutoMapperMappingException
。Json.NET支持ISerializable
,并且基类System.Exception
实现此接口。从参考源可以看出,基类版本GetObjectData
只是将基字段值而不是属性值添加到序列化流中:
info.AddValue("Message", _message, typeof(String));
它的任何子类Exception
在基类之上和之外都拥有其他数据,必须重写GetObjectData
并序列化其自己的数据。例如,这是实现ArgumentOutOfRangeException
:
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
throw new ArgumentNullException("info");
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
info.AddValue("ActualValue", m_actualValue, typeof(Object));
}
现在,从它的源代码,AutoMapperMappingException
重写Exception.Message
到输出附加数据。实际上,基本消息可能为null:
public override string Message
{
get
{
string message = null;
var newLine = Environment.NewLine;
if (Context != null)
{
message = _message + newLine + newLine + "Mapping types:";
message += newLine + string.Format("{0} -> {1}", Context.SourceType.Name, Context.DestinationType.Name);
message += newLine + string.Format("{0} -> {1}", Context.SourceType.FullName, Context.DestinationType.FullName);
var destPath = GetDestPath(Context);
message += newLine + newLine + "Destination path:" + newLine + destPath;
message += newLine + newLine + "Source value:" + newLine + (Context.SourceValue ?? "(null)");
return message;
}
if (_message != null)
{
message = _message;
}
message = (message == null ? null : message + newLine) + base.Message;
return message;
}
}
但是,它不会覆盖GetObjectData()
,这是bug。
要变通解决此问题,您可以编写自己的自定义JsonConverter
并序列化message属性而不是基字段:
public class ExceptionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(AutoMapperMappingException).IsAssignableFrom(objectType);
}
public override bool CanRead { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var exception = (Exception)value;
var obj = JObject.FromObject(exception);
obj["Message"] = exception.Message;
obj.WriteTo(writer);
}
}
这将至少确保该消息存在。但是,仍然不会序列化的ResolutionContext
属性AutoMapperMappingException
,因此生成的反序列化异常将丢失一些数据。
或者,您可以尝试ResolutionContext
使用Json.NET的默认序列化序列化和反序列化,并将其作为属性添加到转换器中。不知道它是否会工作,但可能会。或者尝试报告问题。
(或者,只需记录ToString()
异常的输出,通常就足够了。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句