title: Deserializing custom exceptions in Newtonsoft.Json
body: <p>I've been having trouble deserializing custom exceptions in Newtonsoft.Json version 11.0.2. It works fine in Newtonsoft.Json version 10.0.3.</p>
  
  <p>I serialize and deserialize using - </p>
  
  <pre><code>result = JsonConvert.SerializeObject( &lt;&lt;object of type MyHttpException&gt;&gt; );
  MyHttpException deserializedException = JsonConvert.DeserializeObject&lt;MyHttpException&gt;(result);
  </code></pre>
  
  <p>The error I get during deserialization is a <code>Newtonsoft.Json.JsonSerializationException</code>:</p>
  
  <blockquote>
    <p>Unable to find a constructor to use for type MyHttpException. 
    A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. 
    Path 'HttpStatusCode', line 2, position 19.</p>
  </blockquote>
  
  <p>If I add a parameterless constructor to MyHttpException and MyBaseException, I don't get any exception. But the InnerException is not deserialized and is null.</p>
  
  <p>Is there something obvious I'm missing? I'm not sure why this would work in 10.0.3 and break in 11.0.2.</p>
  
  <p>My exception classes – </p>
  
  <pre><code>public sealed class MyHttpException : MyBaseException
  {
      public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode)
          : base(MyStatusCode) =&gt; HttpStatusCode = httpStatusCode;
  
      public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode, string message)
          : base(MyStatusCode, message) =&gt; HttpStatusCode = httpStatusCode;
  
      public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode, Exception innerException)
          : base(MyStatusCode, innerException) =&gt; HttpStatusCode = httpStatusCode;
  
      public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode, string message, Exception innerException)
          : base(MyStatusCode, message, innerException) =&gt; HttpStatusCode = httpStatusCode;
  
      [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
      private MyHttpException(SerializationInfo info, StreamingContext context)
          : base(info, context) =&gt; HttpStatusCode = (HttpStatusCode)info.GetValue("HttpStatusCode", typeof(HttpStatusCode));
  
      public HttpStatusCode HttpStatusCode { get; set; }
  
      [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
      public override void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          if (info == null)
          {
              throw new ArgumentNullException("info");
          }
  
          info.AddValue("HttpStatusCode", HttpStatusCode);
  
          // MUST call through to the base class to let it save its own state
          base.GetObjectData(info, context);
      }
  }
  
  public abstract class MyBaseException : Exception
  {
      public MyBaseException(int MyStatusCode) =&gt; this.MyStatusCode = MyStatusCode;
  
      public MyBaseException(int MyStatusCode, string message)
          : base(message) =&gt; this.MyStatusCode = MyStatusCode;
  
      public MyBaseException(int MyStatusCode, Exception innerException)
          : base("MyErrorCode: " + MyStatusCode + ". " + MyStatusCodes.GetDescription(MyStatusCode) + ". " + innerException.Message, innerException) =&gt; this.MyStatusCode = MyStatusCode;
  
      public MyBaseException(int MyStatusCode, string message, Exception innerException)
          : base(message, innerException) =&gt; this.MyStatusCode = MyStatusCode;
  
      [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
      protected MyBaseException(SerializationInfo info, StreamingContext context)
          : base(info, context)
      {
          MyStatusCode = info.GetInt32("MyStatusCode");
      }
  
      public int MyStatusCode { get; set; }
  
      [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
      public override void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          if (info == null)
          {
              throw new ArgumentNullException("info");
          }
  
          info.AddValue("MyStatusCode", MyStatusCode);
  
          // MUST call through to the base class to let it save its own state
          base.GetObjectData(info, context);
      }
  }
  </code></pre>
  
  <p>Thanks</p>