Skip to content

Commit

Permalink
rule.adoc
Browse files Browse the repository at this point in the history
  • Loading branch information
mary-georgiou-sonarsource committed Feb 23, 2024
1 parent 09772ba commit 11a6cbb
Showing 1 changed file with 17 additions and 28 deletions.
45 changes: 17 additions & 28 deletions rules/S6934/csharp/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,38 +1,25 @@
The routing system in ASP.NET uses a set of predefined rules and conventions to determine which controller and action method or endpoint to invoke for a given HTTP request. This is typically defined in the `RouteConfig` file in an ASP.NET MVC application, or through attribute routing in an ASP.NET Core application.
However, without some extra configuration on the developer's part sometimes the routing system is not able to properly resolve a route and map it to a certain action/endpoint resulting in unexpected behavior or errors.
The https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing[routing] middleware in https://learn.microsoft.com/en-us/aspnet/core/mvc/overview[ASP.NET Core MVC] uses a set of predefined rules and conventions to determine which controller and action method to invoke for a given HTTP request. This is typically defined with the https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.controllerendpointroutebuilderextensions.mapcontrollerroute[`MapControllerRoute`] method during the application configuration.
However, without some extra configuration on the developer's part sometimes the routing system is not able to properly resolve a route and map it to a certain action resulting in unexpected behavior or errors.

== Why is this an issue?

=== ASP.NET Core web APIS
In ASP.NET MVC, when a https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routing.httpmethodattribute[`HttpMethodAttribute`] (such as https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.httpgetattribute[`HttpGet`], https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.httppostattribute[`HttpPost`], etc) is specified with a given route template at the action level, it's important that its controller also has a https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routeattribute[`RouteAttribute`] defined. If not then the route pattern defined `WebApplication.MapControllerRoute` is applied resulting in a not expected route and potential confusion. This applies also to when https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/areas[`areas`] are defined.

ASP.NET Core supports creating web APIs using controllers or using minimal APIs. Controllers in a web API are classes that derive from `ControllerBase` and contain methods that support web API requests. To enable certain automatic API behaviors such as attribute routing requirements, automatic HTTP 400 responses etc, you should annotate your controller with `ApiController` attribute. However, the `ApiController` attribute makes the `Route` attribute a requirement to ensure that the routing process aligns with the conventions of RESTful APIs. If you don't specify it, then your endpoint will most probably not be accessible by the expected route `[controller]/endpoint`.

== How to fix it

=== ASP.NET Core MVC

In ASP.NET MVC, when a `HttpMethodAttribute` (such as HttpGet, HttpPost, etc.) is specified with a route variable at the action level, it's important that its controller also has a `RouteAttribute` defined. If not then the route pattern defined `WebApplication.MapControllerRoute` is applied resulting in a not expected route and potential confusion. This applies also to when `areas` are defined.


== How to fix it in ASP.NET Core MVC

When any of the controller actions is annotated with a `HttpMethodAttribute', then you should annotate the controller with the `RouteAttribute` as well.

== How to fix it in ASP.NET Core for Web Apis

When a controller is annotated with an `ApiControllerAttribut', then you should annotate the controller with the `RouteAttribute` as well.
When any of the controller actions is annotated with a `HttpMethodAttribute' with a route template, then you should also annotate the controller with the `RouteAttribute` as well.

=== Code examples

==== Noncompliant code example

- Web

[source,csharp,diff-id=1,diff-type=noncompliant]
[source,csharp]
----
public class PersonController : Controller
{
[HttpGet("GetPerson")]
public ActionResult Index() // Noncompliant
public ActionResult Index() // Noncompliant, this action will be reachable by "/root/GetPerson" instead of "/root/Person/GetPerson"
{
return View();
}
Expand All @@ -42,13 +29,13 @@ When a controller is annotated with an `ApiControllerAttribut', then you should

==== Compliant solution

[source,csharp,diff-id=1,diff-type=compliant]
[source,csharp]
----
public class PersonController : Controller
{
[HttpGet]
public ActionResult Index() // Compliant
public ActionResult Index() // Compliant, no route template is given to the attribute
{
return View();
}
Expand All @@ -65,16 +52,18 @@ When a controller is annotated with an `ApiControllerAttribut', then you should
}
----

//=== How does this work?

//=== Pitfalls
== Resources

=== Documentation

//=== Going the extra mile
=== Documentation

* Microsoft Learn - https://learn.microsoft.com/en-us/aspnet/core/mvc/overview[Overview of ASP.NET Core MVC]
* Microsoft Learn - https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing[Routing to controller actions in ASP.NET Core]

//== Resources
//=== Documentation
//=== Articles & blog posts
=== Articles & blog posts
* Medium - https://medium.com/quick-code/routing-in-asp-net-core-c433bff3f1a4[Routing in ASP.NET Core]
//=== Conference presentations
//=== Standards
//=== External coding guidelines
Expand Down

0 comments on commit 11a6cbb

Please sign in to comment.