'How can I convert an empty string value to a nullable date value?

When I use Postman to test my API with a PUT request, I get this error:

"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-fe50a5f13435f11ef5d27de5f91d3c45-47c1ee82a70305a9-00",
"errors": {
    "$.extractionDate": [
        "The JSON value could not be converted to System.Nullable`1[System.DateTime]. Path: $.extractionDate | LineNumber: 0 | BytePositionInLine: 704."
    ]
}

I can see that an empty string that looks like this is being passed to the API:

"extractionDate":""

In my model, I have the ExtractionDate property set as nullable like this:

public DateTime? ExtractionDate { get; set; }

Due to things beyond my control, the old system that is using this API can't pass nulls, it can only pass a blank string for any values that are null.

Is there something else I need to do in order for the JSON to be valid?

Thanks!



Solution 1:[1]

Well, assuming that you have control of the API and the models on that end, you could write a custom JsonConverter<DateTime?> that handles empty strings by returning null.

A simple implementation of the JsonConverter<DateTime?> might look something like this...

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

public class NullableDateTimeConverter : JsonConverter<DateTime?>
{
    public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var @string = reader.GetString();
        if (string.IsNullOrWhiteSpace(@string))
        {
            return null;
        }
        return DateTime.Parse(@string);
    }

    public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
    {
        if (value != null)
        {
            writer.WriteStringValue(value.Value.ToString("o"));
        }
    }
}

Then, you can tell your model to use it with a JsonConverterAttribute.

using System;
using System.Test.Json.Serialization;

public class TheModel
{
    [JsonConverter(typeof(NullableDateTimeConverter))]
    public DateTime? ExtractionDate { get; set; }
}

Solution 2:[2]

You can make an extension method and use it everywhere

    public static DateTime? ParseDateOrDefault(this string date)
    {

        if (string.IsNullOrEmpty(date))
            return null;

        return DateTime.Parse(date);
    }

Then in your api make another public string DateTime variable that will accept the datetime passed in. Make your current DateTime variable internal with getters and setters that have logic with the new extension method.

internal DateTime? MyDate 
{
  get
  {
    return MyDateStringVariable.ParseDateOrDefault();
  }
  ...
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Joshua Robinson
Solution 2 Train