将 AutoMapperMappingException 转换为 JSON
Convert AutoMapperMappingException To JSON
在尝试对某些代码进行故障排除时,我查看了捕获任何未处理异常的日志。
在我的日志函数中,我有以下代码行:
data = JsonConvert.DeserializeObject(exception)
部分数据的值读取,\"Message\":null。当我调试并查看异常时,异常的 Message 属性 有一个值(准确描述了问题)。如果我尝试使用上面的行将不同的异常转换为 JSON,我会在结果 JSON.
中看到消息 属性 的值
我错过了什么?
这看起来像是 AutoMapperMappingException
. Json.NET supports ISerializable
, and the base class System.Exception
implements this interface. As can be seen from the reference source, the base class version of GetObjectData
中的错误,只是添加了 基本字段值 而不是 属性 值 到序列化流:
info.AddValue("Message", _message, typeof(String));
Exception
的任何子class 包含超出基础 class 的额外数据必须需要覆盖 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));
}
现在,从其source code, AutoMapperMappingException
overrides Exception.Message
输出额外的数据。事实上,基本消息可能为空:
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()
,这是错误。
要解决此问题,您可以编写自己的自定义 JsonConverter
并序列化消息 属性 而不是基本字段:
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
property of AutoMapperMappingException
仍然不会被序列化,因此产生的反序列化异常将丢失一些数据。
或者,您可以尝试使用 Json.NET 的默认序列化序列化和反序列化 ResolutionContext
,并将其作为 属性 添加到转换器中。不确定它是否会起作用,但它可能会起作用。或者尝试 report an issue.
(或者,只记录异常的 ToString()
输出,这通常就足够了。)
在尝试对某些代码进行故障排除时,我查看了捕获任何未处理异常的日志。
在我的日志函数中,我有以下代码行:
data = JsonConvert.DeserializeObject(exception)
部分数据的值读取,\"Message\":null。当我调试并查看异常时,异常的 Message 属性 有一个值(准确描述了问题)。如果我尝试使用上面的行将不同的异常转换为 JSON,我会在结果 JSON.
中看到消息 属性 的值我错过了什么?
这看起来像是 AutoMapperMappingException
. Json.NET supports ISerializable
, and the base class System.Exception
implements this interface. As can be seen from the reference source, the base class version of GetObjectData
中的错误,只是添加了 基本字段值 而不是 属性 值 到序列化流:
info.AddValue("Message", _message, typeof(String));
Exception
的任何子class 包含超出基础 class 的额外数据必须需要覆盖 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));
}
现在,从其source code, AutoMapperMappingException
overrides Exception.Message
输出额外的数据。事实上,基本消息可能为空:
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()
,这是错误。
要解决此问题,您可以编写自己的自定义 JsonConverter
并序列化消息 属性 而不是基本字段:
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
property of AutoMapperMappingException
仍然不会被序列化,因此产生的反序列化异常将丢失一些数据。
或者,您可以尝试使用 Json.NET 的默认序列化序列化和反序列化 ResolutionContext
,并将其作为 属性 添加到转换器中。不确定它是否会起作用,但它可能会起作用。或者尝试 report an issue.
(或者,只记录异常的 ToString()
输出,这通常就足够了。)