user845392
user845392

Reputation: 563

Route Parameter Validation with Date Format

I am getting the validation failure message (status code 400) for all inputs, when i change the date format to string, the regex works but DateType validation not working. It accepts 2019-02-31 as a valid input. Any idea how to make it work DateTime parameter type?

    [HttpGet("{date}")]
    public ActionResult<string> Get( [RegularExpression(@"^[0-9]{4}-[0-9]{2}-[0-9]{2}$"), DataType(DataType.Date)] DateTime date)
    {
         return Ok();
    }

Upvotes: 0

Views: 2218

Answers (3)

leik&#252;r
leik&#252;r

Reputation: 105

There is an example here :

https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/create-a-rest-api-with-attribute-routing#get-books-by-publication-date

With dotnet core 3 i had to escape { and } (make them double) and it simply works :

[HttpGet("{date:datetime:regex(\\d{{4}}-\\d{{2}}-\\d{{2}})}")]
public WeatherForecast GetForecast(DateTime date)
...

Upvotes: 0

Edward
Edward

Reputation: 30056

For Route Validation, you should avoid be used for input validation.

Don't use constraints for input validation. If constraints are used for input validation, invalid input results in a 404 - Not Found response instead of a 400 - Bad Request with an appropriate error message. Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

Reference: Route constraint reference

If you want to check the input by Route constraint, you could implement your own constraint by implementing IRouteConstraint.

  1. DateRouteConstraint

    public class DateRouteConstraint : IRouteConstraint
    {
        public static string DateRouteConstraintName = "DateRouteConstraint";
        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            object dateValue;
            if (values.TryGetValue("date", out dateValue))
            {
                DateTime date;
                string[] formats = { "yyyy-MM-dd" };
                if (DateTime.TryParseExact(dateValue.ToString(), formats,
                                CultureInfo.InvariantCulture,
                                DateTimeStyles.None, out date))
                {
    
                    return true;
                }
            }
            return false;
        }
    }
    
  2. Register DateRouteConstraint

    services.AddRouting(options =>
    {
        options.ConstraintMap.Add(DateRouteConstraint.DateRouteConstraintName, typeof(DateRouteConstraint));
    });
    
  3. Use Case

    [HttpGet("{date:DateRouteConstraint}")]
    public ActionResult<string> Get(DateTime date)
    {
        return Ok();
    }
    

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239460

You can't apply a RegularExpression attribute to a DateTime as it's not a string; that attribute is only valid for strings.

You can use a regex route constraint, i.e. [HttpGet("{date:regex(...)}")], but in that scenario, you'd be better off using the datetime constraint instead: [HttpGet("{date:datetime}")].

Upvotes: 0

Related Questions