I'm writing an API in dotnet core. I would like my controller action to take a date (eg. '2019-11-12') as a parameter, so the user doesn't have to provide a full datetime
.
I have the following:
[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{...}
It seems to me that this is probably a common use case, but I haven't been able to find a solution on SO. Can you help?
EDIT:
Should I take a string
as parameter and then create a new DateTime
from this string
? Is this the right way to do it?
The reason why you get a compilation error for this:
[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime.Date birthDate)
{...}
is because the compiler is expecting you to define the data type for the birthDate parameter, but DateTime.Date is not a data type, but a property of the DateTime data type.
Now consider this, tested on .NET Core 2.2:
[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{...}
The query string parameter:
birthDate=2019-11-12
binds successfully to the birthDate parameter in the action (with 0 for the hours, minutes and seconds). So I think your assumption that the user has to provide the full date and time is wrong.
Note: The DateTime.Date property is itself a DateTime with the time value set to 12:00:00 midnight (00:00:00); see https://docs.microsoft.com/en-us/dotnet/api/system.datetime.date?view=netcore-2.2 .
Edit: rather than making it impossible for the user to include the time in the query string parameter, you can instead ignore it (my preference as it is user-friendly):
[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery]DateTime birthDate)
{
DateTime birthDateDate = birthDate.Date;
}
Or you could validate that the hours, minutes and seconds are 0, and create a model state error if they are not (not so user friendly). You can do this using a custom validation attribute:
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;
}
}
Usage:
[HttpGet]
public async Task<ActionResult<IEnumerable<DogDto>>> GetDogsForKennelOnDate([FromQuery]string kennelName, [FromQuery] [Date] DateTime birthDate)
{
...
}
This will now succeed validation:
birthDate=2019-11-12
But this will fail:
birthDate=2019-11-12 11:22:33
However, this will still succeed:
birthDate=2019-11-12 00:00:00
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.