0

I have created a customer exception with custom properties based on SO POST.
However when i log the exception, it is not getting serialized. If i put debugger, then GetObjectData method and SerializableExceptionWithCustomProperties(SerializationInfo info, StreamingContext context) constructor does not get invoked and the logger only logs message and stack trace but not my custom properties

However, I added ToString() method in exception and it is getting hit when i log the exception, and now i can construct the string including my custom properties and return it.

So what's the use of adding Serializable attribute and GetObjectData method and SerializableExceptionWithCustomProperties(SerializationInfo info, StreamingContext context) constructor?

I am using Serilog for logging

[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;
    }
}
LP13
  • 30,567
  • 53
  • 217
  • 400

1 Answers1

0

The purpose of serializatin is e.g. the transport of an object from one system to an other ( e.g. between clirnt and server) where you continue to use the transported object. In your case you simply dump the exception to a sink and it's up to you to define how it is represented as a text by defining te exception message or overriding the ToString() method.