Different JsonSerializerSettings for different values in list

674 Views Asked by At

I am using this setting to serialize a list of objects in dotnet core 2.2:

var settings = new JsonSerializerSettings()
{
    DateFormatString = "MM/dd/yyyy h:mm tt"
}

The problem is I want it to serialize and deserialize DateTimes with "MM/dd/yyyy" if DateTimes time equals to 0 and I found no dynamic way to do it in the same list with both values (DateTimes with different times, 0 or not 0)

1

There are 1 best solutions below

4
On BEST ANSWER

You can write your own json converter for for this.

public class DateTimeStringConverter : JsonConverter
{
    // allowable DateTime formats - update as required
    List<string> DateFormats => new List<string> { "MM/dd/yyyy", "MM/dd/yyyy h:mm tt" };

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var dateStr = (string)reader.Value;
        DateTime date;
        foreach (string format in DateFormats)
        {
            if (DateTime.TryParseExact(dateStr, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
            {
                return date;
            }
        }

        throw new JsonException($"{dateStr} as not a valid date string.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        DateTime date = DateTime.Parse(value.ToString());
        // Time value of DateTime.Today is always "00:00:00"
        if (date.TimeOfDay == DateTime.Today.TimeOfDay)
        {
            serializer.Serialize(writer, date.ToString("MM/dd/yyyy"));
        }
        else
        {
            serializer.Serialize(writer, date.ToString("MM/dd/yyyy h:mm tt"));
        }
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }
}

You could improve this by changing DateFormats to public List and pass through valid DateTime formats when initializing JsonSerializerSettings.

Then you can apply the settings like this:

var settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new DateTimeStringConverter());

// deserialize
var model = JsonConvert.DeserializeObject<YourClass>(json, settings);

// serialize
var serializedJson = JsonConvert.SerializeObject(model, settings);

This was inspired by the answer to this question