使用自定义属性记录异常

时间:2018-04-11 21:56:52

标签: c# asp.net exception-handling

我已根据SO POST创建了包含自定义属性的客户例外 但是,当我记录异常时,它没有被序列化。 如果我放置调试器,则不调用GetObjectData方法和SerializableExceptionWithCustomProperties(SerializationInfo info, StreamingContext context)构造函数,并且记录器仅记录消息和堆栈跟踪,但不记录我的自定义属性

但是,我在异常中添加了ToString()方法,并且在我记录异常时它会受到影响,现在我可以构造包含我的自定义属性的字符串并将其返回。

那么添加Serializable属性和GetObjectData方法以及SerializableExceptionWithCustomProperties(SerializationInfo info, StreamingContext context)构造函数的用途是什么?

我正在使用Serilog进行记录

[Serializable]
// Important: This attribute is NOT inherited from Exception, and MUST be specified 
// otherwise serialization will fail with a SerializationException stating that
// "Type X in Assembly Y is not marked as serializable."
public class SerializableExceptionWithCustomProperties : Exception
{
    private readonly string resourceName;        

    public SerializableExceptionWithCustomProperties()
    {
    }

    public SerializableExceptionWithCustomProperties(string message)
        : base(message)
    {
    }

    public SerializableExceptionWithCustomProperties(string message, Exception innerException)
        : base(message, innerException)
    {
    }

    public SerializableExceptionWithCustomProperties(string message, string resourceName)
        : base(message)
    {
        this.resourceName = resourceName;           
    }

    public SerializableExceptionWithCustomProperties(string message, string resourceName, Exception innerException)
        : base(message, innerException)
    {
        this.resourceName = resourceName;            
    }

    public string ResourceName
    {
        get { return this.resourceName; }
    }

    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
    // Constructor should be protected for unsealed classes, private for sealed classes.
    // (The Serializer invokes this constructor through reflection, so it can be private)
    protected SerializableExceptionWithCustomProperties(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        this.resourceName = info.GetString("ResourceName");
    }               

    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
       // Serialize data for our base classes.  base will verify info != null.
        base.GetObjectData(info, context);

        info.AddValue("ResourceName", this.ResourceName);   
    }

    public override string ToString()
    {
        return base.ToString() + Environment.NewLine + "ResourceName: " + this.ResourceName;
    }
}

1 个答案:

答案 0 :(得分:0)

可选择性的目的是例如将对象从一个系统传输到另一个系统(例如在clirnt和服务器之间),继续使用传输的对象。 在您的情况下,您只需将异常转储到接收器,您可以通过定义te异常消息或覆盖ToString()方法来定义它如何表示为文本。