C# – How to use JsonConverterAttribute

You can use JsonConverterAttribute (from System.Text.Json) to apply a specific JsonConverter to a property. Apply this attribute on a property and specify the JsonConverter type to use, like this:

using System.Text.Json.Serialization;

public class Product
{
    [JsonConverter(typeof(ExpirationDateConverter))]
    public DateTime ExpirationDate { get; set; }
    public DateTime ManufacturedDate { get; set; }
}
Code language: C# (cs)

In this example, it’s applying ExpirationDateConverter (a custom JSON converter) to handle the ExpirationDate. For reference, here’s ExpirationDateConverter’s definition:

public class ExpirationDateConverter : JsonConverter<DateTime>
{
    private const string dateFormat = "yyyy-MM";
    public override void Write(Utf8JsonWriter writer, DateTime date, JsonSerializerOptions options)
    {
        writer.WriteStringValue(date.ToString(dateFormat));
    }
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.ParseExact(reader.GetString(), dateFormat, null);
    }
}
Code language: C# (cs)

Now serialize the object to JSON:

using System.Text.Json;

var options = new JsonSerializerOptions() { WriteIndented = true };

var manufacturedDate = DateTime.Now;
var product = new Product()
{
    ExpirationDate = manufacturedDate.AddYears(2),
    ManufacturedDate = manufacturedDate
};

var json = JsonSerializer.Serialize(product, options);

Console.WriteLine(json);
Code language: C# (cs)

Here’s the JSON this produces:

{
  "ExpirationDate": "2024-02",
  "ManufacturedDate": "2022-02-02T08:03:26.9510435-05:00"
}
Code language: JSON / JSON with Comments (json)

It used ExpirationDateConverter to serialize the ExpirationDate property. This had no effect on the other DateTime property.

Specify custom converter parameters per property

JsonConverterAttribute only handles parameterless JsonConverters. If you need to use a parameterized JsonConverter, you can subclass JsonConverterAttribute. I’ll show an example of how to do that.

1 – Create a parameterized custom converter

The following parameterized custom converter accepts a date format string in the constructor. It uses this format string in the Write() method (serialization) and in the Read() method (deserialization):

using System.Text.Json;
using System.Text.Json.Serialization;

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
	private readonly string Format;
	public CustomDateTimeConverter(string format)
	{
		Format = format;
	}
	public override void Write(Utf8JsonWriter writer, DateTime date, JsonSerializerOptions options)
	{
		writer.WriteStringValue(date.ToString(Format));
	}
	public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		return DateTime.ParseExact(reader.GetString(), Format, null);
	}
}
Code language: C# (cs)

Note: You can change the JSON serialization date format for all DateTime properties with the settings.

2 – Subclass JsonConverterAttribute

Create a custom attribute class that subclasses JsonConverterAttribute. Add constructor parameters and override the CreateConverter() method:

using System.Text.Json.Serialization;

public class JsonCustomDateTime : JsonConverterAttribute
{
	public readonly string Format;
	public JsonCustomDateTime(string format)
	{
		Format = format;
	}
	public override JsonConverter? CreateConverter(Type typeToConvert)
	{
		if (typeToConvert != typeof(DateTime))
			throw new Exception("Can only use this attribute on DateTime properties");

		return new CustomDateTimeConverter(Format);
	}
}
Code language: C# (cs)

The serializer calls CreateConverter() and uses the returned converter to handle the property.

3 – Apply the custom attribute to properties

Add the custom attribute to the DateTime properties and specify the date format for each property:

public class Product
{
    [JsonCustomDateTime("yyyy-MM")]
    public DateTime ExpirationDate { get; set; }

    [JsonCustomDateTime("yyyy-MM-dd")]
    public DateTime ManufacturedDate { get; set; }
}
Code language: C# (cs)

4 – Serialization example

Serialize the Product object:

using System.Text.Json;

var manufacturedDate = DateTime.Now;
var product = new Product()
{
    ExpirationDate = manufacturedDate.AddYears(2),
    ManufacturedDate = manufacturedDate
};

var json = JsonSerializer.Serialize(product);

Console.WriteLine(json);
Code language: C# (cs)

Here’s the JSON produced:

{"ExpirationDate":"2024-02","ManufacturedDate":"2022-02-02"}Code language: JSON / JSON with Comments (json)

Comments are closed.