org.sonar.plugins.csharp.S6965.html Maven / Gradle / Ivy
When building a REST API, it’s
recommended to annotate the controller actions with the available HTTP attributes to be precise about what
your API supports.
Why is this an issue?
- Ambiguity: Without HttpAttributes, it’s unclear which HTTP methods an action method should respond to. This can lead to
confusion and make the code harder to understand and maintain.
- Unsupported HTTP Methods: If an action is not annotated at all or is annotated only with the Route attribute, it accepts all HTTP methods even if
they are not supported by that action, which leads to further confusion.
- Problems with Swagger: Swagger relies on HttpAttributes to generate
parts of the API documentation. These attributes are necessary for the generated documentation to be complete.
- Route path conflicts: Without HttpAttributes, it’s possible to accidentally create action methods that respond to the same
route and HTTP method. This can lead to unexpected behavior and hard-to-diagnose bugs.
- Lack of routing flexibility: The HTTP attributes allow you to define multiple action methods in the same controller that
respond to the same route but different HTTP methods. If you don’t use them, you might have limited flexibility when designing your API.
How to fix it
You should annotate the controller actions with the available HttpMethod attributes. You can still use them in conjunction with the Route
attribute, in case there are multiple templates for one action and you need to set the order. This allows
you to clearly define the HTTP methods each action method should respond to, while still being able to customize your routes.
Exceptions
This rule does not raise if the controller or the action is annotated with [ApiExplorerSettings(IgnoreApi =
true)]
or AcceptsVerbs
attribute.
Code examples
Noncompliant code example
[Route("Customer")] // This route conflicts with GetCustomers action route
public async Task<IResult> ChangeCustomer([FromBody] CustomerData data) // Noncompliant
{
// ...
return Results.Ok();
}
[Route("Customer")] // This route conflicts with ChangeCustomer action route
public async Task<string> GetCustomers() // Noncompliant
{
return _customerRepository.GetAll();
}
Compliant solution
[Route("Customer")]
[HttpPost]
public async Task<IResult> ChangeCustomer([FromBody] CustomerData data) // Compliant
{
// ...
return Results.Ok();
}
[HttpGet("Customer")]
public async Task<string> GetCustomers() // Compliant
{
return _customerRepository.GetAll();
}
Resources
Documentation
- Microsoft Learn - Routing to controller actions in ASP.NET
Core
- Microsoft Learn - Attribute routing with Http
verb attributes
- Microsoft Learn - Get started with
Swashbuckle and ASP.NET Core
- Microsoft Learn - ASP.NET Core Exception
handler
- Microsoft Learn - RouteAttribute Class
© 2015 - 2024 Weber Informatics LLC | Privacy Policy