SonarSource Rules
  • Products

    In-IDE

    Code Quality and Security in your IDE with SonarQube Ide

    IDE extension that lets you fix coding issues before they exist!

    Discover SonarQube for IDE

    SaaS

    Code Quality and Security in the cloud with SonarQube Cloud

    Setup is effortless and analysis is automatic for most languages

    Discover SonarQube Cloud

    Self-Hosted

    Code Quality and Security Self-Hosted with SonarQube Server

    Fast, accurate analysis; enterprise scalability

    Discover SonarQube Server
  • SecretsSecrets
  • ABAPABAP
  • AnsibleAnsible
  • ApexApex
  • AzureResourceManagerAzureResourceManager
  • CC
  • C#C#
  • C++C++
  • CloudFormationCloudFormation
  • COBOLCOBOL
  • CSSCSS
  • DartDart
  • DockerDocker
  • FlexFlex
  • GitHub ActionsGitHub Actions
  • GoGo
  • HTMLHTML
  • JavaJava
  • JavaScriptJavaScript
  • JSONJSON
  • JCLJCL
  • KotlinKotlin
  • KubernetesKubernetes
  • Objective CObjective C
  • PHPPHP
  • PL/IPL/I
  • PL/SQLPL/SQL
  • PythonPython
  • RPGRPG
  • RubyRuby
  • RustRust
  • ScalaScala
  • SwiftSwift
  • TerraformTerraform
  • TextText
  • TypeScriptTypeScript
  • T-SQLT-SQL
  • VB.NETVB.NET
  • VB6VB6
  • XMLXML
  • YAMLYAML
C#

C# static code analysis

Unique rules to find Bugs, Vulnerabilities, Security Hotspots, and Code Smells in your C# code

  • All rules 493
  • Vulnerability46
  • Bug88
  • Security Hotspot24
  • Code Smell335

  • Quick Fix 61
Filtered: 11 rules found
asp.net
    Impact
      Clean code attribute
        1. Actions that return a value should be annotated with ProducesResponseTypeAttribute containing the return type

           Code Smell
        2. ModelState.IsValid should be called in controller actions

           Code Smell
        3. REST API actions should be annotated with an HTTP verb attribute

           Code Smell
        4. Value type property used as input in a controller action should be nullable, required or annotated with the JsonRequiredAttribute to avoid under-posting.

           Code Smell
        5. You should pool HTTP connections with HttpClientFactory

           Code Smell
        6. API Controllers should derive from ControllerBase instead of Controller

           Code Smell
        7. Controllers should not have mixed responsibilities

           Code Smell
        8. A Route attribute should be added to the controller when a route template is specified at the action level

           Code Smell
        9. Use model binding instead of reading raw request data

           Code Smell
        10. ASP.NET controller actions should not have a route template starting with "/"

           Code Smell
        11. Backslash should be avoided in route templates

           Bug

        Controllers should not have mixed responsibilities

        adaptability - modular
        maintainability
        Code Smell
        Quick FixIDE quick fixes available with SonarLint
        • asp.net

        ASP.NET controllers should not have mixed responsibilities. Following the Single Responsibility Principle (SRP), they should be kept lean and focused on a single, separate concern. In short, they should have a single reason to change.

        The rule identifies different responsibilities by looking at groups of actions that use different sets of services defined in the controller.

        Basic services that are typically required by most controllers are not considered:

        • ILogger
        • IMediator
        • IMapper
        • IConfiguration
        • IBus
        • IMessageBus

        The rule currently applies to ASP.NET Core only, and doesn’t cover ASP.NET MVC 4.x.

        It also only takes into account web APIs controllers, i.e. the ones marked with the ApiController attribute. MVC controllers are not in scope.

        Why is this an issue?

        How can I fix it?

        More Info

        Multiple issues can appear when the Single Responsibility Principle (SRP) is violated.

        Harder to read and understand

        A controller violating SRP is harder to read and understand since its Cognitive Complexity is generally above average (see S3776).

        For example, a controller MediaController that is in charge of both the "movies" and "photos" APIs would need to define all the actions dealing with movies, alongside the ones dealing with photos, all defined in the same controller class.

        The alternative is to define two controllers: a MovieController and a PhotoController, each in charge of a smaller number of actions.

        Harder to maintain and modify

        Such complexity makes the controller harder to maintain and modify, slowing down new development and increasing the likelihood of bugs.

        For example, a change in MediaController made for the movies APIs may inadvertently have an impact on the photos APIs as well. Because the change was made in the context of movies, tests on photos may be overlooked, resulting in bugs in production.

        That would not be likely to happen when two distinct controllers, MovieController and a PhotoController, are defined.

        Harder to test

        The controller also becomes harder to test since the test suite would need to define a set of tests for each of the responsibilities of the controller, resulting in a large and complex test suite.

        For example, the MediaController introduced above would need to be tested on all movies-related actions, as well as on all photos-related actions.

        All those tests would be defined in the same test suite for MediaController, which would be affected by the same issues of cognitive complexity as the controller under test by the suite.

        Harder to reuse

        A controller that has multiple responsibilities is less likely to be reusable. Lack of reuse can result in code duplication.

        For example, when a new controller wants to derive from an existing one, it’s less probable that the new controller requires all the behaviors exposed by the reused controller.

        Rather, it’s much more common that the new controller only needs to reuse a fraction of the existing one. When reuse is not possible, the only valid alternative is to duplicate part of the logic in the new controller.

        Higher likelihood of performance issues

        A controller that has multiple responsibilities may end up doing more than strictly necessary, resulting in a higher likelihood of performance issues.

        To understand why, it’s important to consider the difference between ASP.NET application vs non-ASP.NET applications.

        In a non-ASP.NET application, controllers may be defined as Singletons via a Dependency Injection library.

        In such a scenario, they would typically be instantiated only once, lazily or eagerly, at application startup.

        In ASP.NET applications, however, the default is that controllers are instantiated as many times as the number of requests that are served by the web server. Each instance of the controller would need to resolve services independently.

        While service instantiation is typically handled at application startup, service resolution happens every time an instance of controller needs to be built, for each service declared in the controller.

        Whether the resolution is done via Dependency Injection, direct static access (in the case of a Singleton), or a Service Locator, the cost of resolution needs to be paid at every single instantiation.

        For example, the movies-related APIs of the MediaController mentioned above may require the instantiation of an IStreamingService, typically done via dependency injection. Such a service may not be relevant for photos-related APIs.

        Similarly, some of the photos-related APIs may require the instantiation of an IRedEyeRemovalService, which may not work at all with movies.

        Having a single controller would force the developer to deal with both instantiations, even though a given instance of the controller may be used only for photos, or only for movies.

        More complex routing

        A controller that deals with multiple concerns often has unnecessarily complex routing: the route template at controller level cannot factorize the route identifying the concern, so the full route template needs to be defined at the action level.

        For example, the MediaController would have an empty route (or equivalent, e.g. / or ~/) and the actions would need to define themselves the movie or photo prefix, depending on the type of media they deal with.

        On the other hand, MovieController and PhotoController can factorize the movie and photo route respectively, so that the route on the action would only contain action-specific information.

        What is the potential impact?

        As the size and the responsibilities of the controller increase, the issues that come with such an increase will have a further impact on the code.

        • The increased complexity of reading and understanding the code may require the introduction of regions or partial classes, to be able to visually separate the actions related to the different concerns. Those are patches, that don’t address the underlying issue.
        • The increased complexity to maintain and modify will not give incentives to keep the architecture clean, leading to a more tightly coupled and less modular system.
        • The reduced reusability of the code may bring code duplication, which breaks the Don’t repeat yourself (DRY) principle and which itself comes with a whole lot of issues, such as lack of maintainability and consistency.
        • The performance penalty of conflating multiple responsibilities into a single controller may induce the use of techniques such as lazy service resolution (you can find an example of this approach here). Those increase the complexity of the code and make the runtime behavior less predictable.

        Why MVC controllers are not in scope

        Alongside attribute routing, which is typical of web APIs, MVC controllers also come with [conventional routing].

        In MVC, the file structure of controllers is important, since it drives conventional routing, which is specific to MVC, as well as default view mapping.

        For those reasons, splitting an MVC controller into smaller pieces may break core behaviors of the web application such as routing and views, triggering a large refactor of the whole project.

          Available In:
        • SonarQube IdeCatch issues on the fly,
          in your IDE
        • SonarQube CloudDetect issues in your GitHub, Azure DevOps Services, Bitbucket Cloud, GitLab repositories
        • SonarQube Community BuildAnalyze code in your
          on-premise CI
          Available Since
          10.6
        • SonarQube ServerAnalyze code in your
          on-premise CI
          Developer Edition
          Available Since
          10.6

        © 2008-2025 SonarSource SA. All rights reserved.

        Privacy Policy | Cookie Policy | Terms of Use