36

What does it mean for a property to be [Required] and nullable? (example below) It seems that if it is [Required] it couldn't possibly be null (no value), and if it is able to be null it couldn't possibly be [Required].

[Required]
public DateTime? OrderDate { get; set; }
trashr0x
  • 6,457
  • 2
  • 29
  • 39
Pismotality
  • 2,149
  • 7
  • 24
  • 30

4 Answers4

47

The reason for making a property nullable and marked with the [Required] attribute is to protect against under-posting attacks. It also allows you to display an initial empty value in the view rather than the default value for the property. This is typically done with value type properties in view models.

An under-posting attack is where a malicious user modifies the request to omit a value for the property in the request. If the property was DateTime (not nullable), then the DefaultModelBinder will initialize the value its default (01/01/0001) and no ModelState error would be generated. As a result, that value may then be saved even though its not what you may be expecting.

If the property is DateTime? (nullable) and [Required], then if a malicious user did omit the property in the request, then a ModelState error will be generated because a value is expected in the request, and the view would be returned, therefore the invalid data will not be saved.

Refer also Brad Wilson's article Input Validation vs. Model Validation in ASP.NET MVC and the section titled The "Under-Posting" Problem.

  • 1
    so, Nullable: makes sure, that we do not see "0" for integer and some "dafault" date when the entry form is loaded. And [Required] make sure, that value is always entered from the user, Because ModelBinder will not add any "Default" value to it. (as we saw when form got loaded). So, underposting will make the modelstate Invalid. Awesome. I would have never thought of something like this. :) – Unbreakable Aug 28 '17 at 03:17
  • 1
    `This is typically done with value type properties in view models` : what is the meaning of this line? – Unbreakable Aug 28 '17 at 04:40
  • 1
    @Unbreakable. Value types are `int`, `bool`, `DateTime` etc that are not nullable (as opposed to Reference Types which are nullable). Refer [Value Types (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/value-types) –  Aug 28 '17 at 04:43
  • 1
    As a thumb rule, whenever I DO NOT want to show default value and still want the field to be required during POST I will use "?" in conjunction with [Required], and since reference types are nullable by default I don't need "?" with strings and all :) – Unbreakable Aug 28 '17 at 05:33
8

It's nullable so the form doesn't display an initial value like 0001-01-01T00:00:00 that has no meaning.

It's required to force the user to enter something.

Max Toro
  • 28,282
  • 11
  • 76
  • 114
6

It is required for client validation but nullable for DB mapping

Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
6

Required is a data annotation for the view. The view will require it to have a value prior to accepting a form post.

That the value is nullable is related to what is allowed in the database. A value may be null in the database, or the value may be persisted as null.

They are separate aspects.

Travis J
  • 81,153
  • 41
  • 202
  • 273