将具有TimeSpan属性的JSON对象传递给C#WebAPI

问题描述

我有一个WebAPI(用C#编写),一个POST方法接受一个名为 TriggerDelay 的System.TimeSpan-Property的复杂对象,以及一个我从中传递该对象的React Native应用程序JSON格式。

但是,此TimeSpan属性未正确序列化,并且我在API端不断得到00:00:00值。

我正在尝试这样:

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

或者像这样:

"triggerDelay": "30:10:00"

但是仍然没有运气...在API中,它始终是00:00:00。

我将不胜感激!

UPD这是我的模型:

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

我的WebAPI方法

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

这是我的原始JSON对象,该对象在Postman的请求正文中设置:

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

解决方法

Newtonsoft的Json.NET开箱即用地支持TimeSpan序列化/反序列化(如果您愿意,how to switch to Newtonsoft.Json in an ASP.NET Core 3.0 MVC project):

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(似乎是您在使用的自3.0版以来ASP.NET Core中的默认json处理工具)does not have内置了对TimeSpan的支持,因此您将需要实现自定义转换器。最简单的一个看起来像这样:

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());
    }
}

和用法:

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