Required attribute for an integer value

asp.net MvcData Annotations

asp.net Mvc Problem Overview


I have a viewmodel with an Id property

[Required]
public int Id { get; set; }

But I think this attribute is working only for string properties.

When no Id is set, Id has value 0 and the model is valid.

How can I enforce that if no value for a int property is set, the model will be invalid ?

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

Use the Range Attribute.

Set minimum to 1 and maximum to int.MaxValue

[Range(1, int.MaxValue, ErrorMessage = "Value for {0} must be between {1} and {2}.")]

Solution 2 - asp.net Mvc

Change the type to Nullable<int> (shortcut int?) to allow null values.

Solution 3 - asp.net Mvc

For .NET Core (and maybe earlier versions) you can also create a custom attribute to perform the range validation for ease of reuse:

public class Id : ValidationAttribute
{
    protected override ValidationResult IsValid(
        object value,
        ValidationContext validationContext)
    {
        return Convert.ToInt32(value) > 0 ?
            ValidationResult.Success :
            new ValidationResult($"{validationContext.DisplayName} must be an integer greater than 0.");
    }
}

Use the Id attribute like this in your model:

public class MessageForUpdate
{
    [Required, Id]
    public int UserId { get; set; }
    [Required]
    public string Text { get; set; }
    [Required, Id]
    public int ChannelId { get; set; }
}

When the Id is <= 0 this error message is returned:

UserId must be an integer greater than 0.

No need to verify that the value is less than int.MaxValue (although it is nice to display that in the message) because the API will return this error by default before it gets this far even if the value is int.MaxValue + 1:

The JSON value could not be converted to System.Int32

Solution 4 - asp.net Mvc

This is similar to the answer from @Lee Smith, but enables 0 to be valid input, which might be useful in some scenarios.

What you can do is to init the int value to another value then 0, like this:

[Range(0, int.MaxValue)]
public int value{ get; set; } = -1;

It would even be possible to support all values except int.MinValue by doing it like this:

[Range(int.MinValue + 1, int.MaxValue)]
public int value{ get; set; } = int.MinValue;

Solution 5 - asp.net Mvc

If you are using a database, you should use the attributes [Key] and [DatabaseGenerated(DatabaseGenerated.Identity)] and Id shouldn't be NULLABLE.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser256034View Question on Stackoverflow
Solution 1 - asp.net MvcLee SmithView Answer on Stackoverflow
Solution 2 - asp.net MvcJulien LebosquainView Answer on Stackoverflow
Solution 3 - asp.net MvcDustin CView Answer on Stackoverflow
Solution 4 - asp.net MvcDavid BergView Answer on Stackoverflow
Solution 5 - asp.net MvcDominik KoziołView Answer on Stackoverflow