JsonSubTypes 2.0.1
dotnet add package JsonSubTypes --version 2.0.1
NuGet\Install-Package JsonSubTypes -Version 2.0.1
<PackageReference Include="JsonSubTypes" Version="2.0.1" />
paket add JsonSubTypes --version 2.0.1
#r "nuget: JsonSubTypes, 2.0.1"
// 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
JsonSubTypes is a discriminated Json sub-type Converter implementation for .NET
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
}
Registration:
var settings = new JsonSerializerSettings();
settings.Converters.Add(JsonSubtypesConverterBuilder
.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
.Build());
or using syntax with generics:
var settings = new JsonSerializerSettings();
settings.Converters.Add(JsonSubtypesConverterBuilder
.Of<Animal>("Type") // type property is only defined here
.RegisterSubtype<Cat>(AnimalType.Cat)
.RegisterSubtype<Dog>(AnimalType.Dog)
.SerializeDiscriminatorProperty() // ask to serialize the type property
.Build());
De-/Serialization:
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
[JsonConverter(typeof(JsonSubtypes))]
[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\"}," +
"{\"Skill\":\"Painter\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}]";
var persons = JsonConvert.DeserializeObject<IReadOnlyCollection<Person>>(json);
Assert.AreEqual("Painter", (persons.Last() as Artist)?.Skill);
Registration:
settings.Converters.Add(JsonSubtypesWithPropertyConverterBuilder
.Of(typeof(Person))
.RegisterSubtypeWithProperty(typeof(Employee), "JobTitle")
.RegisterSubtypeWithProperty(typeof(Artist), "Skill")
.Build());
or
settings.Converters.Add(JsonSubtypesWithPropertyConverterBuilder
.Of<Person>()
.RegisterSubtypeWithProperty<Employee>("JobTitle")
.RegisterSubtypeWithProperty<Artist>("Skill")
.Build());
A default class other than the base type can be defined
[JsonConverter(typeof(JsonSubtypes))]
[JsonSubtypes.KnownSubType(typeof(ConstantExpression), "Constant")]
[JsonSubtypes.FallBackSubType(typeof(UnknownExpression))]
public interface IExpression
{
string Type { get; }
}
Or with code configuration:
settings.Converters.Add(JsonSubtypesConverterBuilder
.Of(typeof(IExpression), "Type")
.SetFallbackSubtype(typeof(UnknownExpression))
.RegisterSubtype(typeof(ConstantExpression), "Constant")
.Build());
settings.Converters.Add(JsonSubtypesWithPropertyConverterBuilder
.Of(typeof(IExpression))
.SetFallbackSubtype(typeof(UnknownExpression))
.RegisterSubtype(typeof(ConstantExpression), "Value")
.Build());
š 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 =)
License
Product | Versions |
---|---|
.NET | net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows |
.NET Core | netcoreapp1.0 netcoreapp1.1 netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 |
.NET Standard | netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 netstandard2.1 |
.NET Framework | net35 net40 net403 net45 net451 net452 net46 net461 net462 net463 net47 net471 net472 net48 net481 |
MonoAndroid | monoandroid |
MonoMac | monomac |
MonoTouch | monotouch |
Tizen | tizen30 tizen40 tizen60 |
Universal Windows Platform | uap uap10.0 |
Xamarin.iOS | xamarinios |
Xamarin.Mac | xamarinmac |
Xamarin.TVOS | xamarintvos |
Xamarin.WatchOS | xamarinwatchos |
-
.NETFramework 3.5
- Newtonsoft.Json (>= 13.0.1)
-
.NETFramework 4.0
- Newtonsoft.Json (>= 13.0.1)
-
.NETFramework 4.5
- Newtonsoft.Json (>= 13.0.1)
-
.NETFramework 4.6
- Newtonsoft.Json (>= 13.0.1)
-
.NETFramework 4.7
- Newtonsoft.Json (>= 13.0.1)
-
.NETStandard 1.3
- NETStandard.Library (>= 1.6.1)
- Newtonsoft.Json (>= 13.0.1)
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.1)
NuGet packages (571)
Showing the top 5 NuGet packages that depend on JsonSubTypes:
Package | Downloads |
---|---|
Okta.Sdk
Official .NET SDK for the Okta API |
|
Xero.NetStandard.OAuth2
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 |
|
Lusid.Sdk.Preview
LUSID SDK |
|
Lusid.Sdk
LUSID SDK |
|
InfluxDB.Client
The reference client that allows query, write and management (bucket, organization, users) for the InfluxDB 2.x. |
GitHub repositories (20)
Showing the top 5 popular GitHub repositories that depend on JsonSubTypes:
Repository | Stars |
---|---|
BililiveRecorder/BililiveRecorder
Bē«å½ę姬 | BiliBili Stream Recorder | åå©åå©ē“ęå½å¶
|
|
antonpup/Aurora
Unified lighting effects across multiple brands and various games.
|
|
Azure-Samples/cognitive-services-speech-sdk
Sample code for the Microsoft Cognitive Services Speech SDK
|
|
RyanLamansky/dotnet-webassembly
Create, read, modify, write and execute WebAssembly (WASM) files from .NET-based applications.
|
|
jlucansky/Quartzmin
Quartzmin is powerful, easy to use web management tool for Quartz.NET
|
Version | Downloads | Last updated |
---|---|---|
2.0.1 | 417,560 | 10/18/2022 |
2.0.0 | 615 | 10/18/2022 |
1.9.0 | 1,253,389 | 5/9/2022 |
1.8.0 | 8,853,010 | 9/23/2020 |
1.7.0 | 2,002,444 | 3/28/2020 |
1.6.0 | 2,583,360 | 6/24/2019 |
1.5.2 | 3,153,346 | 1/19/2019 |
1.5.1 | 324,840 | 10/15/2018 |
1.5.0 | 88,585 | 8/27/2018 |
1.4.0 | 139,509 | 4/17/2018 |
1.3.1 | 4,672 | 4/12/2018 |
1.3.0 | 52,751 | 1/28/2018 |
1.2.0 | 5,262,216 | 11/22/2017 |
1.1.3 | 48,245 | 11/15/2017 |
1.1.2 | 1,875 | 10/20/2017 |
1.1.1 | 1,480 | 9/21/2017 |
1.1.0 | 6,423 | 9/19/2017 |
1.0.0 | 3,139 | 7/23/2017 |