title: Deserialize an abstract class that has only a getter using Newtonsoft
body: <p>I'm trying to deseralize JSON I'm getting:</p>
  <pre><code>[
  {
      &quot;Name&quot;:&quot;0&quot;,
      &quot;Health&quot;:0,
      &quot;TypeName&quot;:&quot;SpellInfo&quot;,
      &quot;Info&quot;:{
        &quot;Effect&quot;:1,
        &quot;EffectAmount&quot;:4
      }
    },
    {
      &quot;Name&quot;:&quot;1&quot;,
      &quot;Health&quot;:0,
      &quot;TypeName&quot;:&quot;MonsterInfo&quot;,
      &quot;Info&quot;:{
        &quot;Health&quot;:10,
        &quot;AttackDamage&quot;:10
      }
    },
  ...
  ...
  ]
  </code></pre>
  <p>Created a class to handle the JSON:</p>
  <pre><code>    [System.Serializable]
      public class CardDataStructure
      {
          public string Name; 
          public int Health; 
          public string TypeName;
          public Info Info;
      }
  </code></pre>
  <p>I managed to get all the info I needed but the Info. From the research I did, I created a <code>JsonConverter</code> from a link - <a href="https://blog.codeinside.eu/2015/03/30/json-dotnet-deserialize-to-abstract-class-or-interface/" rel="nofollow noreferrer">https://blog.codeinside.eu/2015/03/30/json-dotnet-deserialize-to-abstract-class-or-interface/</a>
  Which is actually pretty close,</p>
  <pre><code>public class InfoConvert: JsonConverter
  {
      public override bool CanConvert(Type objectType)
      {
          return (objectType == typeof(Info));
      }
  
      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
      {
          JObject jo = JObject.Load(reader);
  
          if (jo.ToString().Contains(&quot;Effect&quot;))
          {
              if (jo[&quot;Effect&quot;].Value&lt;string&gt;() is string)
                  return jo.ToObject&lt;SpellInfo&gt;(serializer);
          }
          if (jo.ToString().Contains(&quot;Health&quot;))
          {
              if (jo[&quot;Health&quot;].Value&lt;string&gt;() is string)
                  return jo.ToObject&lt;MonsterInfo&gt;(serializer);
          }  
          return null;
          }
  }
  </code></pre>
  <p>(It would have been better to find it by 'typename' but I couldn't figure out how to do that, so went with something simple)<br />
  When checking 'jo', the properties are there and go to the correct class yet once out of the converter I get default properties and not the once the converter showed.
  I can't find the link but on the Newtonsoft doc it said somewhere there's a problem with deserializing an abstract class and if the abstract class doesn't have a public setter.</p>
  <p>Both monsterinfo and spellinfo inherit from info:</p>
  <pre><code>    [Serializable]
      public abstract class Info
      {
  
      }
  </code></pre>
  <p>The <code>monsterinfo</code> and <code>spellinfo</code> look basically the same. Problem is they don't have a public setters and I cannot change them right now.</p>
  <pre><code>{
      [Serializable]
      public class MonsterInfo: Info
      {
          [SerializeField] 
          private int m_Health;
          public int Health =&gt; m_Health;
          
          [SerializeField]
          private int m_AttackDamage;
          public int AttackDamage =&gt; m_AttackDamage;
          
  
      }
  }
  </code></pre>
  <p>So, when trying to deseralize the JSON:</p>
  <pre><code>string contents = File.ReadAllText(source);
  contents = &quot;{\&quot;cards\&quot;:&quot; + contents + &quot;}&quot;;
  JsonConverter[] converters = { new InfoConvert() };
  cardsData = JsonConvert.DeserializeObject&lt;Cards&gt;(contents, new JsonSerializerSettings() {
  Converters = converters, NullValueHandling = NullValueHandling.Ignore, 
  TypeNameHandling = TypeNameHandling.Auto});
  
          
  </code></pre>
  <p>*Cards is a list of CardDataStructure</p>
  <p>Is it even possible to get the data in Info without giving them a public setter?
  Best I got is all the data inside the JSON and an empty Monster/Spell Info.</p>
  <p>At the end I just need to parse the json I'm getting, but while the 'name', 'health', 'typeinfo' are parsed correctly, info is always an empty object filled with 0s.</p>
  <p>Edit: Corrected some things.</p>