0

I have a project on Asp.net Web Api 2. I faced kind of interesting behavior of .net framework during testing one of the endpoint.

this is the simplified version of endpoint:

    [Route("api/v1/bookings/documenttype/{clientId}/{companyCode}/{year}")]
    [HttpGet]
    [ResponseType(typeof(IEnumerable<UserVoucherType>))]
    public IHttpActionResult GetUserDocumentTypes(int clientId, string companyCode, 
                                                  int year, [FromUri] int? month = null)
    {
        //Do Some work
        return Ok();
    }

the problem here when I send a non integer value as value of 'month' parameter instead of getting bad request or something like this I get null during run time and this cause problem. For example one of the consumer of endpoint were sending '[1,2,3]' and getting all data for whole year instead of getting an error message.

For example for this request I am getting below values that I pointed on ss: http://localhost:64652/api/v1/bookings/documenttype/1/0001/2019?month=[1,2,3] enter image description here

Now my question how can I return a bad request for a case like this.

The month parameter is optional and I can't understand on endpoint did consumer send this parameter null on purpose or they send a not valid value for parameter.

Is there a setting for this ? I was thinking to write a custom paramater binder but isn't this over engineering ? I think the behavior of framework should be default returning bad request or am I missing something?

2
  • you should validate users's input, if failed you can return badrequest, read here on how to return bad request stackoverflow.com/a/10734690/1638261 Commented Dec 17, 2020 at 8:35
  • 1
    @jomsk1e How can I do validate parameter, it is getting null and this can be normal behavior too because of it is optional parameter , the problem I can't understand on endpoint is someone really send month parameter null or send a wrong value and become null. Commented Dec 17, 2020 at 8:55

2 Answers 2

1

You could create a model for your optional params and apply the Range attribute to month.

(This is .NET5 so I'm using [FromQuery], but this should work for [FromUri] too)

public OkResult GetUserDocumentTypes(int clientId, string companyCode, 
                                            int year, [FromQuery] GetUserDocumentTypesOptionalInput optional)
{
//Do Some work
    return Ok();
}

public class GetUserDocumentTypesOptionalInput 
{
    [Range(1, 12, ErrorMessage = "Invalid month")]
    public int? Month {get; set; } // 1 or 0 based? 
}

It will depend on your configuration if you have to manually check ModelState.IsValid to catch the error.


Also, with <TargetFramework>net5.0</TargetFramework> and [FromQuery] int? month = null the following error would be returned:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-65615fa2ff03a141b2cd80d7fc4f9dca-db45cf7466ae6f4f-00",
    "errors": {
        "month": [
            "The value '[1,2,3]' is not valid."
        ]
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for answer , we are using 4.6.1 framework version, for a while we can't update the Framework. But this look helpful to me , is there a documentation about it ?
I added an option that should work for .net framework.
I guess you forgot to add helper class or ?
0

You can change the Route attribute to include the data type constraint.

[Route("api/v1/bookings/documenttype/{clientId}/{companyCode}/{year:int{min:2000}/{month:int?}")]

I have added 2 constraints - data type for month and year, and min value for year.

For more details, refer to the official documentation from Microsoft.

2 Comments

Unfortunately Changing path is not an option for us. The all optional parameters must be query parameter in our api.
Path is not changed here from user's point of view. User will still use the same path like api/v1/bookings/documenttype/1/0001/2019?month=11 The change is suggested on the server side, in the Route attribute on top of the GetUserDocumentTypes(). Let's add constraints on data type and values for the query parameters there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.