S6964 ignores [Required] attributes

  • Summary

Rule csharpsquid:S6964 says to use attributes, but does not recognise the attribute from the (Microsoft) documentation that it links to.

  • What language is this for?

C#

  • Which rule?

csharpsquid:S6964

  • Why do you believe it’s a false-positive/false-negative?

“Property should be annotated .. to avoid under-posting” - gives some suggestions of which annotations, such as [JsonProperty] but does not consider the [Required] attribute.

The [more info] tab for the rule

https://sonarqube.bu-uk.co.uk/coding_rules?open=csharpsquid%3AS6964&rule_key=csharpsquid%3AS6964

links to “Model Validation in ASP.Net 4.x” which explains how to use the [Required] attribute to stop under-posting.

  • Are you using
    • SonarQube Server / Community Build - which version?

Probably 2025.4 but can’t see a definitive version page. Got this by linking via the [i] to documentation.

  • How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)

Example code, c# .net 8:

public class MyRequest
{
    [Required]
    public int MyId { get; set; }

Hi @marc.free,

Thank you for the detailed report. This is intentional behaviour, and here’s the reasoning.

The [Required] attribute validates that a value is not null. For a non-nullable int, null is impossible — when the property is absent from the request body, the JSON deserializer assigns the default value 0 rather than null. [Required] sees a non-null value and validation passes unconditionally. The Microsoft ASP.NET Core documentation explicitly states: “A non-nullable field is always valid, and the [Required] attribute’s error message is never displayed.” (source)

Regarding the documentation link in the rule — the ASP.NET Web API 4.x page does discuss [Required] and under-posting, but it actually prescribes making the property nullable first, then adding [Required]:

“To force clients to set a value, make the property nullable and set the Required attribute: [Required] public decimal? Price { get; set; }

So even the linked docs don’t support [Required] alone on a non-nullable value type. This was also reported and discussed previously in sonar-dotnet#9263.

To actually prevent under-posting for a non-nullable value type, the options are:

  • Make it nullable: public int? MyId { get; set; }
  • Use the required modifier (C# 11+): public required int MyId { get; set; }
  • Annotate with [JsonRequired] from System.Text.Json.Serialization, which enforces presence at the deserialization layer

Note that I created an analyzer that contains rules to find these kinds of issues: