I want to JSON serialize a custom exception object which inherits System.Exception. JsonConvert.SerializeObject seems to ignore properties from the derived type. The problem can be illustrated very simply:
class MyException : Exception {
public string MyProperty { get; set; }
}
class Program {
static void Main(string[] args) {
Console.WriteLine(JsonConvert.SerializeObject(new MyException {MyProperty = "foobar"}, Formatting.Indented));
//MyProperty is absent from the output. Why?
Console.ReadLine();
}
}
I've tried adding the DataContract and DataMember attributes in the correct places. They don't help. How do I get this to work?
To ignore individual properties, use the [JsonIgnore] attribute.
Yes, add prop. PropertyName = prop. UnderlyingName; inside the loop in the resolver. This will cause the property to use its original name.
We still use [JsonIgnore] attribute, adding it to the property which we do not want to be serialized.
ReferenceLoopHandling Property. Gets or sets how reference loops (e.g. a class referencing itself) are handled. The default value is Error. Namespace: Newtonsoft.Json. Assembly: Newtonsoft.Json (in Newtonsoft.Json.dll) Version: 12.0.1+509643a8952ce731e0207710c429ad6e67dc43db.
Because Exception implements ISerializable
, Json.Net uses that to serialize the object by default. You can tell it to ignore ISerializable
like so:
var settings = new JsonSerializerSettings() {
Formatting = Formatting.Indented,
ContractResolver = new DefaultContractResolver() {
IgnoreSerializableInterface = true
}
};
Console.WriteLine(JsonConvert.SerializeObject(new MyException {MyProperty = "foobar"}, settings));
You could also add and retrieve a specific object into the System.Runtime.Serialization.SerializationInfo
store by overriding the GetObjectData
method and the ctor(SerializationInfo, StreamingContext)
:
public class MyCustomException : Exception
{
public string MyCustomData { get; set; }
protected MyCustomException (SerializationInfo info, StreamingContext context) : base(info, context)
{
MyCustomData = info.GetString("MyCustomData");
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("MyCustomData", MyCustomData);
}
}
This way the MyCustomObject
property will get included in serialization and deserialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With