I currently have this controller
[RoutePrefix("api/Home")]
public class HomeController : ApiController
{
[HttpGet]
[Route("")]
public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null){
if (!ModelState.IsValid) //From ApiController.ModelState
{
return BadRequest(ModelState);
}
}
}
I want only the following 3 urls to be matched:
api/Home
(Both id
and AnotherId
are null)api/Home?id=1
(Only Anotherid
is null)api/Home?AnotherId=1
(Only Id
is null)Other urls should return unregistered routes
or error
. Currently, api/Home?asdfanyquery
also returns a match which is not what I desired.
How do I rewrite the controller so that the routes only matches to the 3 urls above?
I ended up creating an ActionFilterAttribute
as suggested in the comments and applying it like so:
public class InvalidQueryStringRejector : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var arguments = actionContext.ActionArguments.Keys;
var queryString = actionContext.Request.GetQueryNameValuePairs()
.Select(q => q.Key);
var invalidParams = queryString.Where(k => !arguments.Contains(k));
if (invalidParams.Any())
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, new
{
message = "Invalid query string parameters",
parameters = invalidParams
});
}
}
}
[RoutePrefix("api/Home")]
public class HomeController : ApiController
{
[InvalidQueryStringRejector] //The custom created ActionFilterAttribute
[HttpGet]
[Route("")]
public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null)
{
if (!ModelState.IsValid) //From ApiController.ModelState
{
return BadRequest(ModelState);
}
}
}