控制器动作中的日期参数

时间:2019-11-13 17:21:27

标签: c# asp.net-core

我正在dotnet核心中编写API。我希望控制器操作将日期(例如“ 2019-11-12”)作为参数,因此用户不必提供完整的datetime

我有以下内容:

[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{...}

在我看来,这可能是一个常见的用例,但是我还没有找到关于SO的解决方案。你能帮忙吗?

编辑:

是否应该将string作为参数,然后从此DateTime创建一个新的string?这是正确的方法吗?

1 个答案:

答案 0 :(得分:3)

您为此得到编译错误的原因:

[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime.Date birthDate)
{...}

是因为编译器期望您为birthDate参数定义数据类型,但是DateTime.Date不是 数据类型,而是DateTime数据类型的属性。

现在考虑一下,已在.NET Core 2.2上进行了测试:

[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{...}

查询字符串参数:

birthDate=2019-11-12

成功绑定到操作中的birthDate参数(小时,分钟和秒均为0)。因此,我认为您关于用户必须提供完整日期和时间的假设是错误的。

注意:DateTime.Date属性本身是一个DateTime,其时间值设置为午夜12:00:00(00:00:00);参见https://docs.microsoft.com/en-us/dotnet/api/system.datetime.date?view=netcore-2.2

编辑:您可以忽略它(而不是让用户在查询字符串参数中包含时间)(我偏爱它是用户友好的):

[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{
    DateTime birthDateDate = birthDate.Date;
}

或者您可以验证小时,分钟和秒是否为0,如果不是,则创建模型状态错误(不是那么用户友好)。您可以使用自定义验证属性来做到这一点:

public sealed class DateAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (validationContext == null)
        {
            throw new ArgumentNullException(nameof(validationContext));
        }

        if (!(value is DateTime))
        {
            return new ValidationResult($"Not a DateTime object ({value}).");
        }

        DateTime date = (DateTime)value;

        if (date.Date != date)
        {
            return new ValidationResult($"Do not specify the time ({value}).");
        }

        return ValidationResult.Success;
    }
}

用法:

[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery] [Date] DateTime birthDate)
{
    ...
}

现在将成功通过验证:

birthDate=2019-11-12

但这将失败:

birthDate=2019-11-12 11:22:33

但是,这仍然会成功:

birthDate=2019-11-12 00:00:00