Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Required query string parameter in ASP.NET Core

Tags:

Using ASP.NET Core 1.1 with VS2015 (sdk 1.0.0-preview2-003131), I have the following controller:

public class QueryParameters {     public int A { get; set; }     public int B { get; set; } }  [Route("api/[controller]")] public class ValuesController : Controller {     // GET api/values     [HttpGet]     public IEnumerable<string> Get([FromQuery]QueryParameters parameters)     {         return new [] { parameters.A.ToString(), parameters.B.ToString() };     }         } 

As you can see, I have two query parameters. What I would like is to have one of them (ex: A) to be required. That is, I would like to use an attribute (if possible) to say that this attribute is required. Then, I would like like ASP.NET to do this validation before even calling my controller.

I would have liked to use the Newtonsoft RequiredAttribute to use the same attributes as I already use to validate the required properties in the PUT/POST content, but since the url is not a JSON string, it is obviously not used.

Any suggestion to have ASP.NET Core automatically check for required query parameters?

Note that I know that I can code the check myself using nullable query parameters but that beats the purpose of letting ASP.NET do the validation before calling my controller, thus keeping my controller tidy.

like image 493
mabead Avatar asked May 10 '17 14:05

mabead


People also ask

How do I make query string mandatory?

The first solution to make query string parameters mandatory is to use Model Binding on the public properties of a class. We make the Number property mandatory by using the [BindRequired] attribute.

What is difference between FromQuery and FromBody?

[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.

Can query parameters be mandatory?

Yes, mandatory parameters can be used in query parameters. In that case you need to put a validation after the API is hit to check whether the value of the parameter is not null and is of specified format.


2 Answers

In ASP.NET Core 2.1 and above you can use top level parameters validation. You can put attributes on parameters

    [HttpGet]     public IActionResult GetDices([BindRequired, Range(1, 6)]int number)     {         if (!ModelState.IsValid)         {             return BadRequest("Invalid number");         }              return Ok(_diceRepo.GetDices(number));     } 

More about this https://programmingcsharp.com/asp-net-parameter-validation/#Top-level_node_validation

like image 121
Valentin Anghel Avatar answered Sep 20 '22 21:09

Valentin Anghel


You can consider using the model binding feature of the framework

According to documentation here: Customize model binding behavior with attributes

MVC contains several attributes that you can use to direct its default model binding behavior to a different source. For example, you can specify whether binding is required for a property, or if it should never happen at all by using the [BindRequired] or [BindNever] attributes.

So I suggest you add a BindRequiredAttribute to the model property.

public class QueryParameters {     [BindRequired]     public int A { get; set; }     public int B { get; set; } } 

From there the framework should be able to handle the binding and updating model state so that you can check the state of the model in the action

[Route("api/[controller]")] public class ValuesController : Controller {     // GET api/values     [HttpGet]     public IActionResult Get([FromQuery]QueryParameters parameters)     {             if (ModelState.IsValid)         {             return Ok(new [] { parameters.A.ToString(), parameters.B.ToString() });         }         return BadRequest();     }         } 

The other option would be to create a custom model binder that would fault the action if the required query string is not present.

Reference: Custom Model Binding

like image 40
Nkosi Avatar answered Sep 19 '22 21:09

Nkosi