6

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"
    }
}
derloopkat
  • 6,232
  • 16
  • 38
  • 45
tekatoka
  • 63
  • 1
  • 4
  • `TimeSpan` is a struct and it can't be `null`. Please Add the relevant part of model, or better - [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – Guru Stron Aug 25 '20 at 23:24
  • There is lack of details. But have you tried this https://stackoverflow.com/questions/19971494/how-to-deserialize-a-unix-timestamp-%CE%BCs-to-a-datetime-from-json – Umang Aug 25 '20 at 23:25
  • Also what is used for deserializaion? `System.Text.Json`, `Json.Net` or something else? – Guru Stron Aug 25 '20 at 23:29
  • Sorry, it is indeed not null, but it is always {00:00:00} I am testing with Postman and sending raw JSON data to the API. – tekatoka Aug 25 '20 at 23:45

1 Answers1

8

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
Guru Stron
  • 102,774
  • 10
  • 95
  • 132