17

I'm trying to deserialize object derived from Exception class:

[Serializable]
public class Error : Exception, ISerializable
{
    public string ErrorMessage { get; set; }
    public Error() { }
}
Error error = JsonConvert.DeserializeObject< Error >("json error obj string"); 

It gives me error:

ISerializable type 'type' does not have a valid constructor.

3
  • Firstly, that's not the best way to extend the Exception class. Commented Aug 6, 2010 at 10:02
  • I'm surprised this even compiles since you haven't actually implemented the ISerializable interface. Commented Aug 6, 2010 at 10:12
  • 1
    ISerializable is defined on Exception class Commented Aug 6, 2010 at 10:15

3 Answers 3

20

Adding a new constructor

public Error(SerializationInfo info, StreamingContext context){}
solved my problem.

Here complete code:

[Serializable]
public class Error : Exception
{
    public string ErrorMessage { get; set; }

    public Error(SerializationInfo info, StreamingContext context) 
    {
        if (info != null)
            this.ErrorMessage = info.GetString("ErrorMessage");
    }

    public override void GetObjectData(SerializationInfo info,StreamingContext context)
    {
        base.GetObjectData(info, context);

        if (info != null)
            info.AddValue("ErrorMessage", this.ErrorMessage);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You shouldn't check info on null, it's guarantee to be not-null :)
7

Alternatively, you can choose the OptIn strategy and define the properties that should be processed. In case of your example:

[JsonObject(MemberSerialization.OptIn)]
public class Error : Exception, ISerializable
{
    [JsonProperty(PropertyName = "error")]
    public string ErrorMessage { get; set; }

    [JsonConstructor]
    public Error() { }
}

(Credits go to this library)

Comments

2

Adding upon already provided nice answers;

If the exception is coming from a java based application, then above codes will fail.

For this, sth. like below may be done in the constructor;

public Error(SerializationInfo info, StreamingContext context)
{
    if (info != null)
    {
        try
        {
            this.ErrorMessage = info.GetString("ErrorMessage");
        }
        catch (Exception e) 
        {
            **this.ErrorMessage = info.GetString("message");**
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.