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)
Hi, does these work in .net 7, cant really get em to function properly.
Hi Eric,
I tested the code in .NET 7 and it’s working as expected. Could you explain the problem you’re running into? Is it giving you an error or is it not applying the converter to the property?