0

I currently have this controller

[RoutePrefix("api/Home")]
public class HomeController : ApiController
{

    [HttpGet]
    [Route("")]
    public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id, [FromUri]int? AnotherId ){

        if (!ModelState.IsValid) //From ApiController.ModelState
        {
            return BadRequest(ModelState);
        }
    }
}

When I try to access /api/Home?id=&AnotherId=1 or /api/Home?id=1&AnotherId=, it returns the following error A value is required but was not present in the request. I have clearly indicated that id or AnotherId should be an optional value.

Why is the ModelState not valid? What am I doing wrong?

John Evans Solachuk
  • 1,953
  • 5
  • 31
  • 67

2 Answers2

1

The route that you have defined is:

[Route("{id?}/{AnotherId?}")]

which means you would call it as follows /api/Home/0/1 where 0 would resolve to the value of id and 1 would resolve to the value of AnotherId.

I believe if you remove that route attribute and just leave the [Route("")] route attribute you should be able to call the method as you are expecting(/api/Home?id=&AnotherId=1 or /api/Home?id=1&AnotherId=) and get the results you are expecting.

peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76
  • Removing it didn't work but thanks for the correction anyway. I have edited my question again. – John Evans Solachuk Nov 16 '17 at 01:03
  • @Mark Does your project also have MVC Controllers? I just tested this locally with a WebApi 2 project and it works as expected, no errors. You shouldn't need the BinderType. I would be interested to know what else you have in your project that is causing this issue. – peinearydevelopment Nov 16 '17 at 03:21
  • It is a default Web API 2 project. Nothing has been added yet except that controller and of course, `config.MapHttpAttributeRoutes();`. Maybe when we do a `/api/Home?&id=` in our get parameters, Web API expects a value to `id`. These urls work though; `/api/Home?id=1` and `/api/Home?AnotherId=2` – John Evans Solachuk Nov 16 '17 at 03:49
1

It seems like ModelState in Web Api doesn't recognize this kind of parameter ?a=&b=. Not exactly sure why but we need to add a [BinderType] to [FormUri] like this:

[RoutePrefix("api/Home")]
public class HomeController : ApiController
{

    [HttpGet]
    [Route("")]
    public IHttpActionResult GetByIdAndAnotherID(
        [FromUri(BinderType = typeof(TypeConverterModelBinder))]int? ID = null,
        [FromUri(BinderType = typeof(TypeConverterModelBinder))]int? AnotherID = null){

        if (!ModelState.IsValid) //From ApiController.ModelState
        {
            return BadRequest(ModelState);
        }
    }
}
John Evans Solachuk
  • 1,953
  • 5
  • 31
  • 67