简体   繁体   中英

Multiple GET() methods with a single parameter result in AmbiguousMatchException: The request matched multiple endpoints

[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
}

[HttpGet("{id}")]
public ActionResult<string> Get([FromRoute]int id)
{
}

[HttpGet]
public ActionResult<IEnumerable<string>> Get()([FromQuery]DateTime dateTime)
{
}

I can reach the second with:

https://localhost:44341/api/Orders/3

But for the first and third:

https://localhost:44341/api/Orders
https://localhost:44341/api/Orders?dateTime=2019-11-01T00:00:00

Both of these return the error:

AmbiguousMatchException

Core 2.2, if it matters.

I ended up just creating a different endpoint for the GetByDate method.


[HttpGet]
public ActionResult<string> Get()
{
    //
}


[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
    //
}


[HttpGet("ByDate/{date}")]
public ActionResult<string> ByDate(DateTime date)
{
    //
}

They can be called as follows:

https://localhost:44341/api/controller
https://localhost:44341/api/controller/1
https://localhost:44341/api/controller/getbydate/2019-11-01

We can have a route at the controller level and handle the string input to parse to int or date as below

 [Route("api/[controller]/{id}")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET api/values/5
        [HttpGet()]
        public ActionResult<string> Get(string id)
        {

            if (int.TryParse(id, out int result))
            {
                return Ok(id);

            }
            else if (DateTime.TryParse(id, out DateTime result1))
            {
                return Ok(id);
            }
            else
                return Ok("Failed");
        }
    }

How about having Id and date as optional parameters? You can still handle the actual search in a seprate methods if you want, but you have one GET method.

    [HttpGet("{id}")]
    public IActionResult Get([FromRoute]int? id [FromQuery]DateTime? dateTime)
    {
      if(id.HasValue)
      {
        //Do Something with the id
      } 
      else if (dateTime.HasValue)
      {
        //Do Something with the date
      }
    else 
    {
     //return all
    }
 }
  1. Have two separate URL routes.
  2. Accept a string parameter and parse it into int or DateTime manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM