16

I have a class SearchError that inherits from Exception, and when ever I try to deserialize it from a valid json I get the following exception:

ISerializable type 'SearchError' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present. Path '', line 1, position 81.

I tried implementing the suggested missing constructor, and it didn't help.

This is the class after implementing the suggested constructor:

public class APIError : Exception
{
    [JsonProperty("error")]
    public string Error { get; set; }

    [JsonProperty("@http_status_code")]
    public int HttpStatusCode { get; set; }

    [JsonProperty("warnings")]
    public List<string> Warnings { get; set; }

    public APIError(string error, int httpStatusCode, List<string> warnings) : base(error)
    {
        this.Error = error;
        this.HttpStatusCode = httpStatusCode;
        this.Warnings = warnings;
    }

    public APIError(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        : base(info, context)
    {
        Error = (string)info.GetValue("error", typeof(string));
        HttpStatusCode = (int)info.GetValue("@http_status_code", typeof(int));
        Warnings = (List<string>)info.GetValue("warnings", typeof(List<string>));
    }
}

Now I'm getting the following exception (also in json.net code):

Member 'ClassName' was not found.

I also tried implementing the same solution as in this related question, also got the same error above.

2
  • Share your code with people.. Commented Jan 6, 2013 at 19:46
  • This question has been answered here: stackoverflow.com/a/3423037/504836 Commented Aug 13, 2013 at 2:25

2 Answers 2

15

This question has been answered here: https://stackoverflow.com/a/3423037/504836

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.

3 Comments

And this answer is useless, because you can't always just add a member to a class you don't own. For example, I have this error trying to serialize a DbUpdateConcurrencyException thrown by the Entity Framework. I have no control over that class or its members or what kind of instance is thrown.
@Lukasz Lysik is correct that the answer needs improving, but the best improvement is, in fact, a simplification. I have confirmed by stepping through code and saving the entire object and its properties that the only statement that must be in GetObjectData is the first one, base.GetObjectData(info, context); I have confirmed that every property gets populated, including the HRESULT, which is protected in .NET 2.0. The same holds for the constructor, too.
Is there any particular reason for this? Is it a bug in JSON.NET? This is a horrible thing to add to hundreds of custom exceptions.
5

As the error says, you are missing the serialization constructor:

public class SearchError : Exception
{
    public SearchError(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context)
    {

    }
}

5 Comments

I've tried your suggestion which I already tried before, and now I'm getting some other exception (see above).
": base(info, context)" throws an Exception "Member 'ClassName' was not found."
@joelnet: that's a problem with your code, not the answer. See MSDN link for example: msdn.microsoft.com/en-us/library/…
@joelnet: the example in the answer is working. We have dozens of classes that are configured this way. In addition, the MSDN link contains a working example. If you are having a specific problem with your code, then you should create a new question rather than downvoting an answer and then asking for help in comments.
The serialization constructor isn't always missing, it could be protected, such as with a DbUpdateConcurrencyException in the Entity Framework. Also, this kind of answer isn't good, because it can't be applied if you don't own the class. This seems more like a bug in JSON.NET at this point for it's inability to find a protected constructor.

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.