Data Annotations Validation
The DataAnnotationsValidator component, placed inside an EditForm, plugs into the surrounding EditContext and hooks its OnValidationRequested and OnFieldChanged events so it can inspect every property on the bound model for attributes from System.ComponentModel.DataAnnotations, such as [Required], [StringLength], [Range], and [EmailAddress]. Without dropping a DataAnnotationsValidator into the form, those attributes are inert metadata; nothing actually runs them.
Cricket analogy: Like a match referee cross-checking every player's equipment against the regulation checklist before play, DataAnnotationsValidator plugs into the EditContext and checks every model property against its DataAnnotations attributes before allowing submission.
Common Validation Attributes
The most common attributes are [Required] for mandatory fields, [StringLength(max, MinimumLength = n)] to bound text length, [Range(min, max)] for numeric bounds, and [RegularExpression(pattern)] for format checks like postal codes; every one of them accepts an ErrorMessage string to override the default generic message with something specific to the field.
Cricket analogy: Like a minimum-overs rule that a match must satisfy to count as valid, [Range(1,50)] on an OversBowled property rejects any value outside that bound, and a custom ErrorMessage explains exactly why, just as an umpire explains a no-ball call.
[Compare(nameof(OtherProperty))] validates that two properties on the same model hold identical values, most commonly used for a password-confirmation field, and its default message can embed the friendly property name via the {0} placeholder so the rendered error reads naturally instead of showing the raw C# property identifier.
Cricket analogy: Like a scorer cross-checking that the official scorebook total matches the electronic scoreboard total before confirming the result, [Compare(nameof(Password))] on a ConfirmPassword property rejects submission unless both fields match exactly.
Displaying Validation Messages
ValidationSummary renders every current validation error for the whole EditContext as a list, typically placed near the top of a form, while ValidationMessage For="@(() => model.Email)" renders only the error tied to that one specific field, typically placed right next to its input, giving you the choice between an aggregate overview and precise inline feedback.
Cricket analogy: Like a full match report listing every incident versus a single close-up replay of one contentious decision, ValidationSummary lists every validation error across the form, while ValidationMessage For=@(() => model.Email) shows only the error tied to that one field.
public class RegistrationModel
{
[Required(ErrorMessage = "Email is required.")]
[EmailAddress(ErrorMessage = "Enter a valid email address.")]
public string Email { get; set; } = string.Empty;
[Required]
[StringLength(100, MinimumLength = 8, ErrorMessage = "Password must be 8-100 characters.")]
public string Password { get; set; } = string.Empty;
[Compare(nameof(Password), ErrorMessage = "Passwords do not match.")]
public string ConfirmPassword { get; set; } = string.Empty;
[Range(13, 120, ErrorMessage = "Age must be between 13 and 120.")]
public int Age { get; set; }
}DataAnnotationsValidator only enforces the attributes present on the model's properties; it has no concept of rules that span multiple properties together. For cross-field logic, such as requiring that an EndDate is after a StartDate, implement IValidatableObject on the model or write a custom ValidationAttribute, both of which DataAnnotationsValidator will also pick up automatically.
Custom Validation Logic
When a rule genuinely spans multiple properties, the cleanest option is implementing IValidatableObject.Validate(ValidationContext) on the model itself, returning a ValidationResult for each violation with the relevant member names attached so ValidationMessage can still target the right field. Alternatively, subclassing ValidationAttribute and overriding IsValid(object value, ValidationContext context) lets you package a reusable single-property rule, such as a custom business-id format checker, as an attribute you can apply anywhere.
Cricket analogy: Like a match official who must judge a run-out by weighing both the throw and the batsman's position together rather than each in isolation, IValidatableObject.Validate lets a model check cross-field rules, such as an EndDate that must be after a StartDate, that no single attribute can express alone.
DataAnnotations validation in Blazor, whether WebAssembly or the interactive portions of a Blazor Web App, runs entirely on the client (or in the interactive circuit) and never touches the server's own validation pipeline automatically. Treat it purely as a UX convenience for fast feedback; every API endpoint or server action that receives this data must independently re-validate it, because a malicious client can bypass client-side checks entirely.
- DataAnnotationsValidator must be placed inside an EditForm to activate DataAnnotations attributes; without it, they do nothing.
- [Required], [StringLength], [Range], and [RegularExpression] are the most common single-property validation attributes.
- Every DataAnnotations attribute accepts a custom ErrorMessage, which can use {0} to insert the property's display name.
- [Compare(nameof(OtherProperty))] validates that two properties on the same model match, commonly used for password confirmation.
- ValidationSummary shows all errors at once; ValidationMessage shows the error for one specific field.
- IValidatableObject.Validate or a custom ValidationAttribute is needed for rules spanning multiple properties.
- Client-side validation is a UX convenience only; servers must always independently revalidate incoming data.
Practice what you learned
1. What component must be placed inside an EditForm to make DataAnnotations attributes take effect?
2. Which attribute would you use to ensure a ConfirmPassword field matches a Password field?
3. What's the difference between ValidationSummary and ValidationMessage?
4. How do you validate a rule that depends on two different properties, such as EndDate being after StartDate?
5. Why can't client-side DataAnnotations validation be treated as a security boundary?
Was this page helpful?
You May Also Like
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics