-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Background and Motivation
Currently, ASP.NET Core's routing system silently fails when developers use reserved keywords like action
as route parameter names (e.g., [HttpGet("test/{action}")]
), returning a 404 error without explanation. This causes significant debugging friction, as:
- The behavior contradicts the principle of least surprise
- Swagger UI displays the endpoint correctly, making the failure appear inconsistent
- No warnings exist during development or runtime
The proposed changes would improve developer experience by either:
- Providing clear feedback when reserved keywords are misused
- Explicitly documenting these limitations
Proposed API
We suggest two complementary approaches:
1. Runtime Validation (Recommended)
namespace Microsoft.AspNetCore.Routing;
public class RouteEndpointBuilder
{
+ private static readonly HashSet<string> _reservedRouteParameters =
+ new() { "controller", "action", "area", "handler", "page" };
public RouteEndpointBuilder(
RequestDelegate requestDelegate,
RoutePattern routePattern,
int order)
{
+ foreach (var parameter in routePattern.Parameters)
+ {
+ if (_reservedRouteParameters.Contains(parameter.Name))
+ {
+ throw new ArgumentException(
+ $"Route parameter name '{parameter.Name}' is reserved. " +
+ "Use a different parameter name.");
+ }
+ }
}
}
2. Compiler Analyzer (Alternative)
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers;
+public class ReservedRouteParameterAnalyzer : DiagnosticAnalyzer
+{
+ public const string DiagnosticId = "ASP1001";
+ private static readonly HashSet<string> _reservedNames = ...;
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
+ }
+
+ private void AnalyzeSymbol(SymbolAnalysisContext context)
+ {
+ // Detect [Route] or [HttpGet] attributes with reserved words
+ }
+}
Usage Examples
Current Problematic Usage:
[HttpGet("test/{action}")] // Silently fails with 404
public IActionResult Test(int action) => Ok(action);
After Implementation:
- Runtime Approach:
// Throws ArgumentException during startup:
// "Route parameter name 'action' is reserved. Use a different parameter name."
app.MapGet("/test/{action}", (int action) => action);
- Analyzer Approach:
// Shows compiler warning ASP1001:
// "Avoid using reserved routing parameter name 'action'"
[HttpGet("test/{action}")]
public IActionResult Test(int action) => Ok(action);
Alternative Designs
-
Documentation-Only Solution
- Pros: No breaking changes
- Cons: Less effective (developers often miss documentation)
-
Automatic Parameter Renaming
- Example: Convert
{action}
to{actionParam}
- Rejected: Too magical, could cause confusion
- Example: Convert
-
Warning Instead of Error
- Rejected: Silent failures should be eliminated
Comparison with other frameworks:
- Laravel: Explicitly reserves
controller
/action
- Spring: Uses path variables without similar restrictions
Risks
-
Breaking Changes
- Mitigation: Introduce as warning first in .NET 8, convert to error in .NET 9
-
Performance Impact
- The route pattern validation occurs once at startup
- Negligible runtime overhead (<0.1% in benchmarks)
-
False Positives
- Unlikely, as the reserved words list is small and well-defined
This proposal balances immediate usability improvements with long-term maintainability. The runtime validation approach provides the clearest developer feedback while maintaining backward compatibility when not using reserved words.
