8

I have 2 methods to handle HTTP GET requests, first one for int type input and the other one for string type input.

//GET : api/Fighters/5
[HttpGet("{id}")]
public async Task<ActionResult<Fighter>> GetFighter(int id) 
{
    var fighter = await _context.Fighters.FindAsync(id);

    if (fighter == null) 
    {
        return NotFound();
    }
    return fighter;
}

// GET: api/Fighters/Alex
[Route("api/Fighters/{name}")]
[HttpGet("{name}")]
public async Task<ActionResult<IEnumerable<Fighter>>> GetFighter (string name) 
{
    return await _context.Fighters.Where(f => f.Name == name).ToListAsync();
}

when i send HTTP GET this exception appears (in Postman):

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches: 

FighterGameService.Controllers.FightersController.GetFighter (FighterGameService)
FighterGameService.Controllers.FightersController.GetFighter (FighterGameService)
FighterGameService.Controllers.FightersController.GetFighter (FighterGameService)
FighterGameService.Controllers.FightersController.GetFighter (FighterGameService)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ProcessFinalCandidates(HttpContext httpContext, CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.Select(HttpContext httpContext, CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.MatchAsync(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.Matching.DataSourceDependentMatcher.MatchAsync(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

GET api/fighters/1 would cause error obviously since "1" could be either int or string so i solved my problem by combining two methods:

// GET: api/Fighters/5
// GET: api/Fighters/Alex
[HttpGet("{idOrName}")]
public async Task<ActionResult<IEnumerable<Fighter>>> GetFighter(string idOrName)
{
    if (Int32.TryParse(idOrName, out int id))
    {
        return await _context.Fighters.Where(f => f.Id == id).ToListAsync();
    }
    else
    {
        return await _context.Fighters.Where(f => f.Name == idOrName).ToListAsync();
    }

}

this works however this doesn't feel right at all. What is the proper way to handle this problem?

3 Answers 3

19

You can use route constraint

[HttpGet("{id:int}")]
public async Task<ActionResult<Fighter>> GetFighter(int id) 

[HttpGet("{name}")]
public async Task<ActionResult<IEnumerable<Fighter>>> GetFighter (string name)
Sign up to request clarification or add additional context in comments.

1 Comment

Why cant you just type {name:alpha}? It throws 404 HttpError when doing that
8

I had this problem in Core 3.0. I finally found the solution was to put a route attribute on the action - e.g. [Route("NodeInfo")]. That fixed it

1 Comment

This is the correct answer at least when you have an endpoint with the same signature
-1

Please follow the solution for .Net Core 3.1 or higher Version:Use [Route("RouteName")]

[HttpPost]
        [Route("CreateUserRole")]
       // [Authorize(Roles = "admin")]
        [ProducesResponseType(StatusCodes.Status201Created)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<IActionResult> CreateUserRole([FromBody] AssignUserRole assignUserRole)
        {
            try
            {
                _logger.LogInfo("Attempted submission attempted");

                if (assignUserRole == null)
                {
                    _logger.LogWarn("Empty request submitted");
                    return BadRequest(ModelState);
                }
                if (!ModelState.IsValid)
                {
                    _logger.LogWarn("User data was incomplete");
                    return BadRequest(ModelState);
                }
                var User = _Mapper.Map<Users>(assignUserRole);
                _UserRoleRepository.AssignRoleUser(assignUserRole);
                _logger.LogInfo("User Role created");
                Audit_logs audit = new Audit_logs()
                {
                    uid = User.id,
                    action = "Create User Role",
                    log = $"{assignUserRole.rolename} Role has created",
                    datetime = DateTime.Now
                };
                await _audit_Logs.Create(audit);
                return Created("Create User Role", new { assignUserRole });
            }
            catch (Exception ex)
            {
                return InternalError($"{ex.Message}-{ex.InnerException}");
            }

        }

1 Comment

Please consider editing your answer, as it lacks explanation, context and the code is not relative the OP's original code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.