ASP.NET Web API avoids invalid parameters in query string

Given the following action by the web API controller:

// GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } 

The following query is not interrupted even if the parameter in the query string does not exist:

  http://localhost:22297/api/values?someinvalidparameter=10 

Is there a way to ensure that all parameters in the query string are valid parameters for the action being called?

+5
source share
2 answers

You can write an action filter that checks that all request parameters are present in the action parameters, and throws it if not.

 using System; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http.Controllers; using System.Web.Http.Filters; namespace My.Namespace.Filters { /// <summary> /// Action filter that checks that parameters passed in the query string /// are only those that we specified in methods signatures. /// Otherwise returns 404 Bad Request. /// </summary> public class ValidateQueryParametersAttribute : ActionFilterAttribute { /// <summary> /// This method runs before every WS invocation /// </summary> /// <param name="actionContext"></param> public override void OnActionExecuting(HttpActionContext actionContext) { //check that client does not use any invalid parameter //but just those that are required by WS methods var parameters = actionContext.ActionDescriptor.GetParameters(); var queryParameters = actionContext.Request.GetQueryNameValuePairs(); if (queryParameters.Select(kvp => kvp.Key).Any(queryParameter => !parameters.Any(p => p.ParameterName == queryParameter))) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest); } } } } 
+6
source

In order to work well with validation support, I created my own action selector, which allows you to bind URI parameters to objects of complex type without duplication.

So, you can do the following with this action selector:

 public class CarsByCategoryRequestCommand { public int CategoryId { get; set; } public int Page { get; set; } [Range(1, 50)] public int Take { get; set; } } public class CarsByColorRequestCommand { public int ColorId { get; set; } public int Page { get; set; } [Range(1, 50)] public int Take { get; set; } } [InvalidModelStateFilter] public class CarsController : ApiController { public string[] GetCarsByCategoryId( [FromUri]CarsByCategoryRequestCommand cmd) { return new[] { "Car 1", "Car 2", "Car 3" }; } public string[] GetCarsByColorId( [FromUri]CarsByColorRequestCommand cmd) { return new[] { "Car 1", "Car 2" }; } } 

You can then register an action filter to validate user input to complete the request and return a "400 Bad Request" response along with validation error messages:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class InvalidModelStateFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (!actionContext.ModelState.IsValid) { actionContext.Response = actionContext.Request.CreateErrorResponse( HttpStatusCode.BadRequest, actionContext.ModelState); } } } 

Check out the posts below for more information about this action selector and how to get it:

+2
source

All Articles