将AutoMapperMappingException转换为JSON

杰森·里奇迈尔(Jason Richmeier)

在尝试对某些代码进行故障排除时,我查看了捕获任何未处理的异常的日志。

在我的日志功能中,我有以下代码行:

data = JsonConvert.DeserializeObject(exception)

数据值的一部分读取为\“ Message \”:null。当我调试并查看异常时,异常的Message属性具有一个值(该值准确地描述了问题)。如果我尝试使用上面的行将其他异常转换为JSON,则会在生成的JSON中看到Message属性的值。

我想念什么?

数据库

这看起来像中的错误AutoMapperMappingExceptionJson.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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章