我正在dotnet核心中编写API。我希望控制器操作将日期(例如“ 2019-11-12”)作为参数,因此用户不必提供完整的datetime
。
我有以下内容:
[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{...}
在我看来,这可能是一个常见的用例,但是我还没有找到关于SO的解决方案。你能帮忙吗?
编辑:
是否应该将string
作为参数,然后从此DateTime
创建一个新的string
?这是正确的方法吗?
答案 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