Is this a bug in JSON.NET or Entity Framework or am I doing something wrong while trying to serialize a list of Exceptions with JSON.NET?

前端 未结 3 1321
野性不改
野性不改 2021-01-21 11:41

Got this error when trying to serialize a set of errors:

\"ISerializable type \'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException\' does not have a valid co

3条回答
  •  情话喂你
    2021-01-21 12:13

    You can do it with a contract resolver if you accept to use only base exception fields. Must be used with TypeNameHandling = TypeNameHandling.All;

    public class ISafeSerializationInfoContractResolver : DefaultContractResolver
    {
        protected override JsonContract CreateContract(Type objectType)
        {
            JsonContract contract = base.CreateContract(objectType);
    
            if (contract is JsonISerializableContract)
            {
                JsonISerializableContract serializable = contract as JsonISerializableContract;
                if (serializable.ISerializableCreator == null && typeof(Exception).IsAssignableFrom(objectType))
                {
                    serializable.ISerializableCreator = p =>
                    {
                        SerializationInfo info = (SerializationInfo)p[0];
                        StreamingContext context = (StreamingContext)p[1];
    
                        Exception exception = (Exception)Activator.CreateInstance(typeof(Exception), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null,
                        new object[] { info, context }, CultureInfo.InvariantCulture);
    
                        object realException = Activator.CreateInstance(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture);
    
                        FieldInfo[] fields = typeof(Exception).GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    
                        foreach (FieldInfo field in fields)
                        {
                            field.SetValue(realException, field.GetValue(exception));
                        }
    
                        return realException;
                    };
                }
            }
    
            return contract;
        }
    }
    

提交回复
热议问题