Ilya Chernomordik
Ilya Chernomordik

Reputation: 30205

Why does not Aspnet.Core model validation throw an exception on Nullable properties?

The following code in C# will throw an InvalidOperationException because it's not allowed to access Value when it is not set.

int? a = null;
Console.Writeline(a.Value);

I have the following code in AspNet.Core:

public class Request
{
    [Range(10, 20]
    public int? Field1 {get; set;}

    [Range(10, 20]
    public MyStruct Field2 {get; set;}
}

public struct MyStruct
{
    public int Value => throw new Exception();
}

When model validation happens framework just throws an exception because it tries to read all the properties of MyStruct and it obviously cannot read Value. But if I have only nullable field, validation works just fine even though Value there throws an exception as well.

Is there some magic that is just hardcoded to not do that for nullable or is there some way I can have the same behaviour in my code? I.e. I want the validation to not throw an exception for my class.

I have a suspicion is that this is either a hardcoded check or it's some syntactic sugar that makes Nullable struct possible to assign and compare to null.

Upvotes: 0

Views: 412

Answers (1)

Jonathon Chase
Jonathon Chase

Reputation: 9704

If you take a look at the reference source for the RangeAttribute, you'll see this at the beginning of the IsValid method:

// Automatically pass if value is null or empty. RequiredAttribute should be used to assert a value is not empty.
if (value == null) {
    return true;
}

So this is by design. As the comment suggests, if you have a nullable type and want to confirm there is a value, you should use the RequiredAttribute.

public class Request
{
    [Required]
    [Range(10, 20]
    public int? Field1 {get; set;}

    [Range(10, 20]
    public MyStruct Field2 {get; set;}
}

With Nullable<T> the rules are a bit different for how it's properties work.

Properties on the Nullable<T> type work even if the instance is null, which would normally throw on other types.

int? val = null;
Console.WriteLine(val.HasValue); // No NullReferenceException
Console.WriteLine(val == null); // True

Upvotes: 1

Related Questions