The request matched multiple endpoints in ASP.NET Core
By FoxLearn 3/7/2025 4:34:00 AM 94
500 - Internal Server Error Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches: Controllers.ProductController.GetByCategory Controllers.ProductController.GetByProductName
If you're using Swagger, the UI may show a generic error: "Failed to load API definition … response status is 500." In Visual Studio, you can find the detailed error in the ASP.NET Core Web Server output: SwaggerGeneratorException: Conflicting method/path combination.
This error occurs when multiple controller methods have the same HTTP method and path combination, even if the path parameters are different. The framework can't determine which controller method to call, leading to the AmbiguousMatchException
.
For example, you might have the following ambiguous controller methods:
[HttpGet("{category}")] public IEnumerable<Product> GetByCategory(string category) { // Return products for the specified category } [HttpGet("{productName}")] public Product GetByProductName(string productName) { // Return product by name }
To resolve this issue, you need to disambiguate the paths. There are two main options:
Option 1: Use Route Constraints
You can specify the type of the path parameters using route constraints to make it clear which controller method should be invoked.
[HttpGet("{category:alpha}")] public IEnumerable<Product> GetByCategory(string category) { // Return products for the specified category } [HttpGet("{productName:alpha}")] public Product GetByProductName(string productName) { // Return product by name }
Here’s how this disambiguates the request:
- If the path parameter is alphabetic (
category
), the route will matchGetByCategory(string category)
.- Example:
GET /products/electronics
routes toGetByCategory("electronics")
.
- Example:
- If the path parameter is also alphabetic (
productName
), the route will matchGetByProductName(string productName)
.- Example:
GET /products/phone
routes toGetByProductName("phone")
.
- Example:
You can also explore other route constraints available in ASP.NET Core for more specific matching, such as {category:int}
for integers or {id:guid}
for GUIDs.
Option 2: Change the Paths to Be Different
Alternatively, you can make the paths distinct by changing the route for each method.
Consider this setup, where two methods conflict with the same HTTP method and path (GET /products
):
[HttpGet] public IEnumerable<Product> GetAll() { // Get all products } [HttpGet] public Product GetWithQuery([FromQuery]string productName) { // Get product by name }
Both methods map to GET /products
, so you need to change the paths to disambiguate them:
[HttpGet("all")] public IEnumerable<Product> GetAll() { // Get all products } [HttpGet("search")] public Product GetWithQuery([FromQuery]string productName) { // Get product by name }
Now, these two methods will handle the following requests:
GET /products/all
– CallsGetAll()
.GET /products/search?productName=tablet
– CallsGetWithQuery("tablet")
.
Another option is to combine the methods into one and make the query string parameter optional, allowing flexibility in handling both cases in a single method.
- How to securely reverse-proxy ASP.NET Core
- How to Retrieve Client IP in ASP.NET Core Behind a Reverse Proxy
- Only one parameter per action may be bound from body in ASP.NET Core
- How to Create a custom model validation attribute in ASP.NET Core
- How to disable ModelStateInvalidFilter in ASP.NET Core
- How to fix LoginPath not working in ASP.NET Core
- Synchronous operations are disallowed
- Async SSE endpoint in ASP.NET Core