Skip to main content

jsonConverterSourceGenerator by Aviationexam

Nuget / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

Original Readme

note

Build Status NuGet MyGet feedz.io

Aviationexam.GeneratedJsonConverters.SourceGenerator

Motivation for this library are polymorphic contracts with discriminator property not present as first property.

i.e. this JSON

{
"baseProperty": 1,
"$type": 2,
"anotherLeafProperty": 2
}

is deserialized correctly into AnotherLeafContract using this library.

And string based enum serialization.

Install

<ItemGroup>
<PackageReference Include="Aviationexam.GeneratedJsonConverters.SourceGenerator" Version="0.1.0" PrivateAssets="all" />
</ItemGroup>

How to use library

<PropertyGroup>
<!-- DefaultJsonSerializerContext configuration is required to generate UseEnumConverters method -->
<AVI_EJC_DefaultJsonSerializerContext_ClassAccessibility>public</AVI_EJC_DefaultJsonSerializerContext_ClassAccessibility>
<AVI_EJC_DefaultJsonSerializerContext_Namespace>NamespaceOf.My.Json.Serializer.Context</AVI_EJC_DefaultJsonSerializerContext_Namespace>
<AVI_EJC_DefaultJsonSerializerContext_ClassName>MyJsonSerializerContext</AVI_EJC_DefaultJsonSerializerContext_ClassName>

<!-- Allowed options BackingType, FirstEnumName. Default value FirstEnumName -->
<AVI_EJC_DefaultEnumSerializationStrategy>BackingType</AVI_EJC_DefaultEnumSerializationStrategy>

<!-- Allowed options UseBackingType, UseEnumName, or UseBackingType|UseEnumName (DeserializationStrategy is Flags enum). Default value UseEnumName -->
<AVI_EJC_DefaultEnumDeserializationStrategy>UseBackingType|UseEnumName</AVI_EJC_DefaultEnumDeserializationStrategy>
</PropertyGroup>
// file=contracts.cs
using Aviationexam.GeneratedJsonConverters.Attributes;

[JsonPolymorphic] // notice, that attributes are from `Aviationexam.GeneratedJsonConverters.Attributes` namespace, not `System.Text.Json.Serialization`
[JsonDerivedType(typeof(LeafContract), typeDiscriminator: nameof(LeafContract))]
[JsonDerivedType(typeof(AnotherLeafContract), typeDiscriminator: 2)]
[JsonDerivedType<GenericLeafContract>(typeDiscriminator: nameof(GenericLeafContract))]
public abstract class BaseContract
{
public int BaseProperty { get; set; }
}
public sealed class LeafContract : BaseContract
{
public int LeafProperty { get; set; }
}
public sealed class AnotherLeafContract : BaseContract
{
public int AnotherLeafProperty { get; set; }
}
public sealed class GenericLeafContract : BaseContract
{
public int Property { get; set; }
}

[EnumJsonConverter] // this use project defined configuration
public enum EMyEnum
{
[EnumMember(Value = "C")]
A,
[EnumMember(Value = "D")]
B,
}

[EnumJsonConverter(
SerializationStrategy = EnumSerializationStrategy.FirstEnumName,
DeserializationStrategy = EnumDeserializationStrategy.UseEnumName
)]
public enum EMyEnumWithExplicitConfiguration
{
[EnumMember(Value = "C")]
A,
[EnumMember(Value = "D")]
B,
}

[DisableEnumJsonConverter]
public enum EMyIgnoredEnum
{
C,
D,
}

// file=MyJsonSerializerContext.cs
using System.Text.Json.Serialization;

[JsonSerializable(typeof(BaseContract))] // this line is neccesary, generator searches for JsonSerializableAttribute with argument type decorated by JsonPolymorphicAttribute
[JsonSerializable(typeof(LeafContract))] // notice, it's necessary to specify leaf types
[JsonSerializable(typeof(AnotherLeafContract))]
[JsonSerializable(typeof(GenericLeafContract))]

[JsonSerializable(typeof(EMyEnum))] // only necessary for not referenced enums from other contracts
[JsonSerializable(typeof(EMyEnumWithExplicitConfiguration))]
public partial class MyJsonSerializerContext : JsonSerializerContext
{
static MyJsonSerializerContext()
{
// register generated converters to options
UsePolymorphicConverters(s_defaultOptions.Converters);
UseEnumConverters(s_defaultOptions.Converters);
}
}

About

note

Json Polymorphic generator

How to use

Example ( source csproj, source files )

This is the CSharp Project that references jsonConverterSourceGenerator

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aviationexam.GeneratedJsonConverters.SourceGenerator" Version="0.1.11" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// ReSharper disable once CheckNamespace
namespace Aviationexam.GeneratedJsonConverters.Attributes;

/// <summary>
/// When placed on an enum, indicates that generator should not report missing <see cref="EnumJsonConverterAttribute" />
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Enum, AllowMultiple = false, Inherited = false)]
internal sealed class DisableEnumJsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute
{
}

Usefull

Download Example (.NET C# )

Share jsonConverterSourceGenerator

https://ignatandrei.github.io/RSCG_Examples/v2/docs/jsonConverterSourceGenerator

In the same category (Serializer) - 4 other generators

GenPack

JsonPolymorphicGenerator

ProtobufSourceGenerator

System.Text.Json