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;
}
}