Bob
Bob

Reputation: 1524

How do I configure Model Binding with multiple controller methods of the same HTTP verb (and query parameters)?

Well, I'm clearly doing something wrong here trying to get my REST API endpoints to route for these three use cases.
I get a 500 with the following:

The request matched multiple endpoints. Matches: 

Abc.FooBar.Controllers.FooController.GetByBar (Abc.FooBar)
Abc.FooBar.Controllers.FooController.Get (Abc.FooBar)
Abc.FooBar.Controllers.FooController.GetOnlyActive (Abc.FooBar)

I'm trying to allow the following functionality:

  1. GET api/foo/ (returns all foo)
  2. GET api/foo?onlyActive=false (returns all foo, even inactive ones)
  3. GET api/foo?bar=123... (returns all foo whose bar equals 123...)

So I've tried this with two controller methods, and then this more verbose three, but it doesnt seem to be able to pick up my attributes for instructing it to match on these query parameters. Any ideas?

[Route("api/[controller]")]
[ApiController]
public class FooController : ControllerBase
{
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<IEnumerable<Foo>>> Get()
    {
        //
    }

    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<IEnumerable<Foo>>> GetOnlyActive([FromQuery(Name = "onlyActive")] bool onlyActive)
    {
        //
    }

    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<IEnumerable<Foo>>> GetByBar([FromQuery(Name = "bar")] Guid bar)
    {
        //
    }
}

Upvotes: 2

Views: 61

Answers (1)

SBFrancies
SBFrancies

Reputation: 4240

Have you considered using a single method with optional parameters then applying your logic within it:

[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<IEnumerable<Foo>>> GetOnlyActive([FromQuery] bool onlyActive = false, [FromQuery] Guid? bar = null)
{
    //
}

Upvotes: 1

Related Questions