Pass JSON object with a TimeSpan property to C# WebAPI

Viewed 5804

I have a WebAPI (written in C#), a POST-method accepting a complex object with a System.TimeSpan-Property named TriggerDelay, and a React Native application from where I am passing this object in JSON format.

However, this TimeSpan-property is not serializing properly and I keep getting 00:00:00-value on the API side.

I am trying like this:

"triggerDelay":{
        "hours": "30",
        "minutes": "10",
        "seconds": "0"
    },

OR like this:

"triggerDelay": "30:10:00"

But still no luck... In the API, it is always 00:00:00.

I would appreciate any help!

UPD Here is my Model:

public class Alarm
{
    public Guid Id { get; set; } = Guid.NewGuid();
    [...other properties...]       
    public TimeSpan TriggerDelay {get; set;} 
}

My WebAPI Method:

public async Task<IActionResult> Publish([FromBody] Alarm alarm) {}

And here is my raw JSON object, set in the body of the request in Postman:

{
 "id": "d17ef748-f378-4728-c6c2-9dfab1efce5b",
  [...other properties...]
 "triggerDelay":{
        "hours": "30",
        "minutes": "10",
        "seconds": "0"
    }
}
1 Answers

Newtonsoft's Json.NET supports TimeSpan serialization/deserializion out of the box (how to switch to Newtonsoft.Json in an ASP.NET Core 3.0 MVC project if you decide to) :

public class MyClass
{
    public TimeSpan Interval { get; set; }
}

var json = @"{ ""Interval"":""00:00:42""}";
Console.WriteLine(JsonConvert.DeserializeObject<MyClass>(json).Interval.TotalSeconds); // prints 42

System.Text.Json (the default json handling tool in ASP.NET Core since 3.0 which, it seems, you are using) does not have built-in support for TimeSpan at the moment, so you will need to implement custom converter. Simplest one would look like this:

public class TimeSpanConverter : System.Text.Json.Serialization.JsonConverter<TimeSpan>
{
    public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return TimeSpan.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

And usage:

public class MyClass
{
    [System.Text.Json.Serialization.JsonConverterAttribute(typeof(TimeSpanConverter))]
    public TimeSpan Interval { get; set; }
}

Console.WriteLine(System.Text.Json.JsonSerializer.Deserialize<MyClass>(json).Interval.TotalSeconds); // prints 42
Related