aspnetcore/tutorials/razor-pages/validation/includes/validation6.md
:::moniker range="= aspnetcore-6.0"
In this section, validation logic is added to the Movie model. The validation rules are enforced any time a user creates or edits a movie.
A key tenet of software development is called DRY ("Don't Repeat Yourself"). Razor Pages encourages development where functionality is specified once, and it's reflected throughout the app. DRY can help:
The validation support provided by Razor Pages and Entity Framework is a good example of the DRY principle:
The xref:System.ComponentModel.DataAnnotations namespace provides:
[DataType] that help with formatting and don't provide any validation.Update the Movie class to take advantage of the built-in [Required], [StringLength], [RegularExpression], and [Range] validation attributes.
The validation attributes specify behavior to enforce on the model properties they're applied to:
The [Required] and [MinimumLength] attributes indicate that a property must have a value. Nothing prevents a user from entering white space to satisfy this validation.
The [RegularExpression] attribute is used to limit what characters can be input. In the preceding code, Genre:
The RegularExpression Rating:
Genre.The [Range] attribute constrains a value to within a specified range.
The [StringLength] attribute can set a maximum length of a string property, and optionally its minimum length.
Value types, such as decimal, int, float, DateTime, are inherently required and don't need the [Required] attribute.
The preceding validation rules are used for demonstration, they are not optimal for a production system. For example, the preceding prevents entering a movie with only two chars and doesn't allow special characters in Genre.
Having validation rules automatically enforced by ASP.NET Core helps:
Run the app and navigate to Pages/Movies.
Select the Create New link. Complete the form with some invalid values. When jQuery client-side validation detects the error, it displays an error message.
Notice how the form has automatically rendered a validation error message in each field containing an invalid value. The errors are enforced both client-side, using JavaScript and jQuery, and server-side, when a user has JavaScript disabled.
A significant benefit is that no code changes were necessary in the Create or Edit pages. Once data annotations were applied to the model, the validation UI was enabled. The Razor Pages created in this tutorial automatically picked up the validation rules, using validation attributes on the properties of the Movie model class. Test validation using the Edit page, the same validation is applied.
The form data isn't posted to the server until there are no client-side validation errors. Verify form data isn't posted by one or more of the following approaches:
OnPostAsync method. Submit the form by selecting Create or Save. The break point is never hit.When JavaScript is disabled in the browser, submitting the form with errors will post to the server.
Optional, test server-side validation:
Disable JavaScript in the browser. JavaScript can be disabled using browser's developer tools. If you can't disable JavaScript in the browser, try another browser.
Set a break point in the OnPostAsync method of the Create or Edit page.
Submit a form with invalid data.
Verify the model state is invalid:
if (!ModelState.IsValid)
{
return Page();
}
Alternatively, Disable client-side validation on the server.
The following code shows a portion of the Create.cshtml page scaffolded earlier in the tutorial. It's used by the Create and Edit pages to:
The Input Tag Helper uses the DataAnnotations attributes and produces HTML attributes needed for jQuery Validation on the client-side. The Validation Tag Helper displays validation errors. See Validation for more information.
The Create and Edit pages have no validation rules in them. The validation rules and the error strings are specified only in the Movie class. These validation rules are automatically applied to Razor Pages that edit the Movie model.
When validation logic needs to change, it's done only in the model. Validation is applied consistently throughout the application, validation logic is defined in one place. Validation in one place helps keep the code clean, and makes it easier to maintain and update.
Examine the Movie class. The System.ComponentModel.DataAnnotations namespace provides formatting attributes in addition to the built-in set of validation attributes. The [DataType] attribute is applied to the ReleaseDate and Price properties.
The [DataType] attributes provide:
<a> for URL's and <a href="mailto:EmailAddress.com"> for email.Use the [RegularExpression] attribute to validate the format of the data. The [DataType] attribute is used to specify a data type that's more specific than the database intrinsic type. [DataType] attributes aren't validation attributes. In the sample application, only the date is displayed, without time.
The DataType enumeration provides many data types, such as Date, Time, PhoneNumber, Currency, EmailAddress, and more.
The [DataType] attributes:
mailto: link can be created for DataType.EmailAddress.DataType.Date in browsers that support HTML5.data-, pronounced "data dash", attributes that HTML 5 browsers consume.DataType.Date doesn't specify the format of the date that's displayed. By default, the data field is displayed according to the default formats based on the server's CultureInfo.
The [Column(TypeName = "decimal(18, 2)")] data annotation is required so Entity Framework Core can correctly map Price to currency in the database. For more information, see Data Types.
The [DisplayFormat] attribute is used to explicitly specify the date format:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
The ApplyFormatInEditMode setting specifies that the formatting will be applied when the value is displayed for editing. That behavior may not be wanted for some fields. For example, in currency values, the currency symbol is usually not wanted in the edit UI.
The [DisplayFormat] attribute can be used by itself, but it's generally a good idea to use the [DataType] attribute. The [DataType] attribute conveys the semantics of the data as opposed to how to render it on a screen. The [DataType] attribute provides the following benefits that aren't available with [DisplayFormat]:
[DataType] attribute can enable the ASP.NET Core framework to choose the right field template to render the data. The DisplayFormat, if used by itself, uses the string template.Note: jQuery validation doesn't work with the [Range] attribute and DateTime. For example, the following code will always display a client-side validation error, even when the date is in the specified range:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
It's a best practice to avoid compiling hard dates in models, so using the [Range] attribute and DateTime is discouraged. Use Configuration for date ranges and other values that are subject to frequent change rather than specifying it in code.
The following code shows combining attributes on one line:
Get started with Razor Pages and EF Core shows advanced EF Core operations with Razor Pages.
The DataAnnotations applied to the class changes the schema. For example, the DataAnnotations applied to the Title field:
null value.The Movie table currently has the following schema:
CREATE TABLE [dbo].[Movie] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (MAX) NULL,
[ReleaseDate] DATETIME2 (7) NOT NULL,
[Genre] NVARCHAR (MAX) NULL,
[Price] DECIMAL (18, 2) NOT NULL,
[Rating] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);
The preceding schema changes don't cause EF to throw an exception. However, create a migration so the schema is consistent with the model.
From the Tools menu, select NuGet Package Manager > Package Manager Console. In the PMC, enter the following commands:
Add-Migration New_DataAnnotations
Update-Database
Update-Database runs the Up method of the New_DataAnnotations class.
Use the following commands to add a migration for the new DataAnnotations:
dotnet ef migrations add New_DataAnnotations
dotnet ef database update
dotnet ef database update runs the Up method of the New_DataAnnotations class.
Examine the Up method:
The updated Movie table has the following schema:
CREATE TABLE [dbo].[Movie] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (60) NOT NULL,
[ReleaseDate] DATETIME2 (7) NOT NULL,
[Genre] NVARCHAR (30) NOT NULL,
[Price] DECIMAL (18, 2) NOT NULL,
[Rating] NVARCHAR (5) NOT NULL,
CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);
For information on deploying to Azure, see Tutorial: Build an ASP.NET Core app in Azure with SQL Database.
Thanks for completing this introduction to Razor Pages. Get started with Razor Pages and EF Core is an excellent follow up to this tutorial.
[!div class="step-by-step"] Previous: Add a new field :::moniker-end