Dajbych.net


How C# Nullable Reference Types Affects your ASP.NET Core Routing

, 2 minutes to read

net2015 logo

I thought that the new C# 8.0 feature – non-nullable reference types – was just an IntelliSense feature powered by Roslyn that prevents null reference exceptions. I was wrong. It may affect how your application works in many ways. More specifically, everything that uses reflection can start behaving differently. This includes ASP.NET Core routing. Some bindings can stop working when no additional code changes are applied.

Let us see it with an example. Differentiation between nullable and non-nullable reference types can be turned on in the .csproj file:

<PropertyGroup>
  <Nullable>enable</Nullable>
</PropertyGroup>

Do not think it does not apply either to the annotations value:

<PropertyGroup>
  <Nullable>annotations</Nullable>
</PropertyGroup>

The route may look like this:

[HttpPost]
public async Task MyMethod([Required, FromBody] MyContract contract) {
  ...
}

public class MyContract {
  public string MyValue { get; set; }
  ...
}

MyValue does not have the Required attribute, so even if the JSON request does not have the myValue property, binding between the HTTP request and MyMethod will work. That is true unless you enable nullable reference types. Once you do that, you must declare that MyValue can be null because it is the default value when the property is not included in the request. When the type is not nullable, the default value cannot be applied, and the property is required automatically by the syntax. The Required attribute in this case would be redundant. It also becomes redundant in the contract parameter declaration.

public class MyContract {
  public string? MyValue { get; set; }
  ...
}

MyContract above has MyValue of type string?, which means that the property is optional. The contract will continue to work like before when nullable reference types were enabled.