Search code examples
asp.netasp.net-core

AmbiguousMatchException: The request matched multiple endpoints - Index and Error


I receive following error:

AmbiguousMatchException: The request matched multiple endpoints. Matches:

BeyondTrustConsole.Controllers.BT_ChallengeResponseController.Index (BeyondTrustConsole)
BeyondTrustConsole.Controllers.BT_ChallengeResponseController.Error (BeyondTrustConsole)

my controller looks like that:

using System.Diagnostics;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BeyondTrustConsole.Models;
using BeyondTrustConsole.ViewModels;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Security.Claims;

namespace BeyondTrustConsole.Controllers;

[Authorize(Policy = "Role_ChallengeResponse")]
[Route("ChallengeResponse")]
public class BT_ChallengeResponseController : Controller
{
    public BT_ChallengeResponseController(ILogger<BT_ChallengeResponseController> logger, IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
    {
        ...
    }

    [Route("", Name = "default")]
    [Route("Index")]
    public IActionResult Index()
    {
        ...
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

So I don't understand why it is trying to access the Error function. What I want to archive is that I can access Index by https://localhost:8443/ChallengeResponse/Index and https://localhost:8443/ChallengeResponse

My Program.cs is that:

if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
    // This will add live editing during debugging
    builder.Services.AddRazorPages()
        .AddRazorRuntimeCompilation();
} else {
    builder.Services.AddRazorPages();
}

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseForwardedHeaders();
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
else
{
    app.UseDeveloperExceptionPage();
    app.UseForwardedHeaders();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseCertificateForwarding();

app.UseAuthentication();
app.UseAuthorization();
   
if (app.Environment.IsDevelopment())
{
    // To ignore the [Authorize] attribute on the controllers
    app.MapControllers().WithMetadata(new AllowAnonymousAttribute());
}

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}"
    //defaults: new { controller = "Home", action = "Index" }
    );

// https://stackoverflow.com/questions/59949443/how-to-fix-error-404-when-logging-out-on-an-asp-net-core-mvc-app-against-azure-a
app.MapRazorPages();

app.Run();

Can please someone point me in the correct direction? Thanks


Solution

  • Thanks OP for sharing another solution which add an order for the current route like this [Route("", Order = -1)] which could avoid to create a new route in the application.

    ===========================

    I can reproduce your issue in my side when I add [Route("ChallengeResponse")] to any of my controller class because it break the default mapping rule which defining as your codes below. The same when only adding [Route("Index")] to the action method. It will make the routing to this action method to be localhost:port/index instead of the default localhost:port/controller/index. We can refer to what .net core web API project routing rule. The API controller has it's routing rule and if we have 2 Get methods inside one API controller, then we need to give concrete route name to the Get methods.

    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}"
        //defaults: new { controller = "Home", action = "Index" }
        );
    

    enter image description here

    One of the solution is adding [Route("Error")] to public IActionResult Error() so that each action method in this controller has it's concrete routing.