Я бы предложил использовать fluentvalidation , поскольку он позволяет разделять и повторно использовать правила проверки.
В вашем случае, предполагая, что startdate
является частью CalendarAvailabilityRequest
, вы бы добавиливалидатор для запроса dto:
public class CalendarAvailabilityRequestValidator :
AbstractValidator<CalendarAvailabilityRequest>
{
public CalendarAvailabilityRequestValidator()
{
RuleFor(request => request.StartDate)
.Must(BeAValidDateFormat).WithMessage("Date must follow the format: yyyy-mm-dd")
.NotNull().WithMessage("A start date must be provided.");
}
// will only match yyyy-mm-dd
private static bool BeAValidDateFormat(string date)
=> Regex.IsMatch(date, "2\d{3}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$", RegexOptions.Compiled);
}
В вашем контроллере вы создаете валидатор и позволяете ему проверять:
[Route("{providerName}/CalendarAvailability")]
[HttpGet]
public Task<IActionResult> GetCalendarAvailability(CalendarAvailabilityRequest request)
{
var validationResult = new CalendarAvailabilityRequestValidator().Validate(request);
if (!validationResult.IsValid)
{
Log.Warning(validationResult.Errors.ToString());
return BadRequest(validationResult.Errors);
}
var statDate = DateTime.ParseExact(request.StartDate, "yyyy-mm-dd", CultureInfo.InvariantCulture);
//TODO: calendar availability logic
return OK();
}
Конечно, вы также можете использовать регулярное выражение сверху и подтвердите запрос в вашем контроллере.
Другой вариант - попробовать перехватить, используя DateTime.ParseExact
что-то вроде этого:
try
{
var statDate = DateTime.ParseExact(request.StartDate, "yyyy-mm-dd", CultureInfo.InvariantCulture);
}
catch(exception ex)
{
Log.Warning("Request for {startdate} was invalid: {message}", request.StartDate, ex.Message);
return BadRequest(ex.message);
}
Но я бы рекомендовал избегать попытки перехватакогда вы можете проверить ввод, если вам действительно не нужно.