shows a model class that is annotated with validation attributes. The [ClassicMovie] attribute is a custom validation attribute and the others are built in. Not shown is [ClassicMovieWithClientValidator], which shows an alternative way to implement a custom attribute.
C#Copy
publicclassMovie
{
publicint Id { get; set; }
[Required]
[StringLength(100)]
publicstring Title { get; set; } = null!;
[ClassicMovie(1960)]
[DataType(DataType.Date)]
[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }
[Required]
[StringLength(1000)]
publicstring Description { get; set; } = null!;
[Range(0, 999.99)]
publicdecimal Price { get; set; }
public Genre Genre { get; set; }
publicbool Preorder { get; set; }
}
Built-in attributes
Here are some of the built-in validation attributes:
or parameters as if they had been attributed with the [Required(AllowEmptyStrings = true)] attribute. Consider the following code:
C#Copy
publicclassPerson
{
publicstring Name { get; set; }
}
If the app was built with <Nullable>enable</Nullable>, a missing value for Name in a JSON or form post results in a validation error. Use a nullable reference type to allow null or missing values to be specified for the Name property:
Non-nullable properties on generic types and [Required] attribute
Non-nullable properties on generic types must include the [Required] attribute when the type is required. In the following code, TestRequired is not required:
C#Copy
publicclassWeatherForecast<T>
{
public string TestRequired { get; set; } = null!;
public T? Inner { get; set; }
}
In the following code, TestRequired is explicitly marked as required:
C#Copy
using System.ComponentModel.DataAnnotations;
publicclassWeatherForecast<T>
{
[Required] public string TestRequired { get; set; } = null!;
public T? Inner { get; set; }
}
[Required] validation on the server
On the server, a required value is considered missing if the property is null. A non-nullable field is always valid, and the [Required] attribute's error message is never displayed.
However, model binding for a non-nullable property may fail, resulting in an error message such as The value '' is invalid. To specify a custom error message for server-side validation of non-nullable types, you have the following options:
Make the field nullable (for example,decimal?instead ofdecimal).
Non-nullable types and strings are handled differently on the client compared to the server. On the client:
A value is considered present only if input is entered for it. Therefore, client-side validation handles non-nullable types the same as nullable types.
Whitespace in a string field is considered valid input by the jQuery Validation
method. Server-side validation considers a required string field invalid if only whitespace is entered.
As noted earlier, non-nullable types are treated as though they had a [Required(AllowEmptyStrings = true)] attribute. That means you get client-side validation even if you don't apply the [Required(AllowEmptyStrings = true)] attribute. But if you don't use the attribute, you get a default error message. To specify a custom error message, use the attribute.
attribute implements client-side validation that requires calling a method on the server to determine whether field input is valid. For example, the app may need to verify whether a user name is already in use.
To implement remote validation:
Create an action method for JavaScript to call. The jQuery Validation
property of the [Remote] attribute lets you validate combinations of fields against data on the server. For example, if the User model had FirstName and LastName properties, you might want to verify that no existing users already have that pair of names. The following example shows how to use AdditionalFields:
operator simplifies later refactoring. The action method for this validation must accept both firstName and lastName arguments:
C#Copy
[AcceptVerbs("GET", "POST")]
public IActionResult VerifyName(string firstName, string lastName)
{
if (!_userService.VerifyName(firstName, lastName))
{
return Json($"A user named {firstName}{lastName} already exists.");
}
return Json(true);
}
When the user enters a first or last name, JavaScript makes a remote call to see if that pair of names has been taken.
To validate two or more additional fields, provide them as a comma-delimited list. For example, to add a MiddleName property to the model, set the [Remote] attribute as shown in the following example:
object, which provides additional information, such as the model instance created by model binding.
The following example validates that the release date for a movie in the Classic genre isn't later than a specified year. The [ClassicMovie] attribute:
in the model class, as shown in the following example:
C#Copy
public class ValidatableMovie : IValidatableObject
{
privateconstint _classicYear = 1960;
publicint Id { get; set; }
[Required]
[StringLength(100)]
publicstring Title { get; set; } = null!;
[DataType(DataType.Date)]
[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }
[Required]
[StringLength(1000)]
publicstring Description { get; set; } = null!;
[Range(0, 999.99)]
publicdecimal Price { get; set; }
public Genre Genre { get; set; }
publicbool Preorder { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Genre == Genre.Classic && ReleaseDate.Year > _classicYear) { yield return new ValidationResult( $"Classic movies must have a release year no later than {_classicYear}.", new[] { nameof(ReleaseDate) }); } }