JsonSubTypes 2.0.1

dotnet add package JsonSubTypes --version 2.0.1
NuGet\Install-Package JsonSubTypes -Version 2.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JsonSubTypes" Version="2.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add JsonSubTypes --version 2.0.1
#r "nuget: JsonSubTypes, 2.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install JsonSubTypes as a Cake Addin
#addin nuget:?package=JsonSubTypes&version=2.0.1

// Install JsonSubTypes as a Cake Tool
#tool nuget:?package=JsonSubTypes&version=2.0.1


JsonSubTypes is a discriminated Json sub-type Converter implementation for .NET

Build status Code Coverage Quality Gate Status NuGet NuGet CodeFactor FOSSA Status

DeserializeObject with custom type property name

[JsonConverter(typeof(JsonSubtypes), "Kind")]
public interface IAnimal
    string Kind { get; }

public class Dog : IAnimal
    public string Kind { get; } = "Dog";
    public string Breed { get; set; }

public class Cat : IAnimal {
    public string Kind { get; } = "Cat";
    public bool Declawed { get; set;}

The second parameter of the JsonConverter attribute is the JSON property name that will be use to retreive the type information from JSON.

var animal = JsonConvert.DeserializeObject<IAnimal>("{\"Kind\":\"Dog\",\"Breed\":\"Jack Russell Terrier\"}");
Assert.AreEqual("Jack Russell Terrier", (animal as Dog)?.Breed);

N.B.: This only works for types in the same assembly as the base type/interface and either in the same namespace or with a fully qualified type name.

DeserializeObject with custom type mapping

[JsonConverter(typeof(JsonSubtypes), "Sound")]
[JsonSubtypes.KnownSubType(typeof(Dog), "Bark")]
[JsonSubtypes.KnownSubType(typeof(Cat), "Meow")]
public class Animal
    public virtual string Sound { get; }
    public string Color { get; set; }

public class Dog : Animal
    public override string Sound { get; } = "Bark";
    public string Breed { get; set; }

public class Cat : Animal
    public override string Sound { get; } = "Meow";
    public bool Declawed { get; set; }
var animal = JsonConvert.DeserializeObject<IAnimal>("{\"Sound\":\"Bark\",\"Breed\":\"Jack Russell Terrier\"}");
Assert.AreEqual("Jack Russell Terrier", (animal as Dog)?.Breed);

N.B.: Also works with other kind of value than string, i.e.: enums, int, ...

SerializeObject and DeserializeObject with custom type property only present in JSON

This mode of operation only works when JsonSubTypes is explicitely registered in JSON.NET's serializer settings, and not through the [JsonConverter] attribute.

public abstract class Animal
    public int Age { get; set; }

public class Dog : Animal
    public bool CanBark { get; set; } = true;

public class Cat : Animal
    public int Lives { get; set; } = 7;

public enum AnimalType
    Dog = 1,
    Cat = 2


var settings = new JsonSerializerSettings();
    .Of(typeof(Animal), "Type") // type property is only defined here
    .RegisterSubtype(typeof(Cat), AnimalType.Cat)
    .RegisterSubtype(typeof(Dog), AnimalType.Dog)
    .SerializeDiscriminatorProperty() // ask to serialize the type property

or using syntax with generics:

var settings = new JsonSerializerSettings();
    .Of<Animal>("Type") // type property is only defined here
    .SerializeDiscriminatorProperty() // ask to serialize the type property


var cat = new Cat { Age = 11, Lives = 6 }

var json = JsonConvert.SerializeObject(cat, settings);

Assert.Equal("{\"Lives\":6,\"Age\":11,\"Type\":2}", json);

var result = JsonConvert.DeserializeObject<Animal>(json, settings);

Assert.Equal(typeof(Cat), result.GetType());
Assert.Equal(11, result.Age);
Assert.Equal(6, (result as Cat)?.Lives);

DeserializeObject mapping by property presence

[JsonSubtypes.KnownSubTypeWithProperty(typeof(Employee), "JobTitle")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Artist), "Skill")]
public class Person
    public string FirstName { get; set; }
    public string LastName { get; set; }

public class Employee : Person
    public string Department { get; set; }
    public string JobTitle { get; set; }

public class Artist : Person
    public string Skill { get; set; }

or using syntax with generics:

string json = "[{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," +
                "{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," +

var persons = JsonConvert.DeserializeObject<IReadOnlyCollection<Person>>(json);
Assert.AreEqual("Painter", (persons.Last() as Artist)?.Skill);


    .RegisterSubtypeWithProperty(typeof(Employee), "JobTitle")
    .RegisterSubtypeWithProperty(typeof(Artist), "Skill")



A default class other than the base type can be defined

[JsonSubtypes.KnownSubType(typeof(ConstantExpression), "Constant")]
public interface IExpression
    string Type { get; }

Or with code configuration:

    .Of(typeof(IExpression), "Type")
    .RegisterSubtype(typeof(ConstantExpression), "Constant")
    .RegisterSubtype(typeof(ConstantExpression), "Value")

💖 Support this project

If this project helped you save money or time or simply makes your life also easier, you can give me a cup of coffee =)

  • Support via PayPal
  • Bitcoin — You can send me bitcoins at this address: 33gxVjey6g4Beha26fSQZLFfWWndT1oY3F


FOSSA Status

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.3 is compatible.  netstandard1.4 was computed.  netstandard1.5 was computed.  netstandard1.6 was computed.  netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net35 is compatible.  net40 is compatible.  net403 was computed.  net45 is compatible.  net451 was computed.  net452 was computed.  net46 is compatible.  net461 was computed.  net462 was computed.  net463 was computed.  net47 is compatible.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen30 was computed.  tizen40 was computed.  tizen60 was computed. 
Universal Windows Platform uap was computed.  uap10.0 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (677)

Showing the top 5 NuGet packages that depend on JsonSubTypes:

Package Downloads

Official .NET SDK for the Okta API


This is a .NETStandard SDK library, used to communicate with the Xero API using OAuth2.0. See https://github.com/XeroAPI/Xero-NetStandard for more information




The reference client that allows query, write and management (bucket, organization, users) for the InfluxDB 2.x.



GitHub repositories (24)

Showing the top 5 popular GitHub repositories that depend on JsonSubTypes:

Repository Stars
录播姬 | mikufans 生放送录制
Sample code for the Microsoft Cognitive Services Speech SDK
Unified lighting effects across multiple brands and various games.
Create, read, modify, write and execute WebAssembly (WASM) files from .NET-based applications.
Quartzmin is powerful, easy to use web management tool for Quartz.NET
Version Downloads Last updated
2.0.1 9,252,211 10/18/2022
2.0.0 9,500 10/18/2022
1.9.0 4,695,710 5/9/2022
1.8.0 17,804,180 9/23/2020
1.7.0 2,878,245 3/28/2020
1.6.0 4,517,805 6/24/2019
1.5.2 5,285,949 1/19/2019
1.5.1 469,003 10/15/2018
1.5.0 94,336 8/27/2018
1.4.0 182,943 4/17/2018
1.3.1 5,821 4/12/2018
1.3.0 72,969 1/28/2018
1.2.0 8,620,713 11/22/2017
1.1.3 62,383 11/15/2017
1.1.2 2,945 10/20/2017
1.1.1 2,417 9/21/2017
1.1.0 7,406 9/19/2017
1.0.0 8,470 7/23/2017