Got this error when trying to serialize a set of errors:
\"ISerializable type \'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException\' does not have a valid co
According to the Json.net documentation,
ISerializable
Types that implement ISerializable are serialized as JSON objects. When serializing, only the values returned from ISerializable.GetObjectData are used; members on the type are ignored. When deserializing, the constructor with a SerializationInfo and StreamingContext is called, passing the JSON object's values.
In situations where this behavior is not wanted, the JsonObjectAttribute can be placed on a .NET type that implements ISerializable to force it to be serialized as a normal JSON object.
Since you don't owe the DbUpdateConcurrencyException
class, A workaround could be to create a custom exception class which derive from the DbUpdateConcurrencyException
and Mark it with attribute JsonObject
.
[JsonObject]
class CustomException : DbUpdateConcurrencyException
{
public CustomException(string message) : base(message) { }
}
// Serialize the new customException
var json = JsonConvert.SerializeObject(
new CustomException("hi"), serializationSettings);
//shall not throw error now
DbUpdateConcurrencyException err =
JsonConvert.DeserializeObject(json, serializationSettings);
This is a just a POC that I tried to make it work for JSON.Net. It makes no sense to create custom classes for all type which inherits ISerializable
and doesn't have required constructor. May be you can try creating Castle core DynamicProxy
generator to wrap the thrown exception which are ISerializable
and mark them with JsonObject
attribute on-the-fly before serializing them.
And you're right. Json.net is not able to find the protected constructor because inheritance goes like
DbUpdateConcurrencyException <- DbUpdateException <- DataException
And DataException class have the Protected constructor which json.net is looking for. Every exception class in .Net framework which is derived from SystemException
have this constructor as protected constructor but DbUpdateException
&& DbUpdateConcurrencyException
doesn't have it. So you can guess who to blame now (IMO EF).
Following are the classes I found which have the standard serializable constructor missing and would throw exception during deserialization.
I wrote this issue to EF team here.