100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET Framework

Data Annotations and Validation

How to use Data Annotation attributes to declaratively validate model properties, and how MVC surfaces those rules on both server and client.

Models and DataIntermediate8 min readJul 10, 2026
Analogies

Declarative Validation with Data Annotations

Data Annotations are attributes from the System.ComponentModel.DataAnnotations namespace that you apply directly to model properties to declare validation rules without writing imperative if-statements. Attributes like [Required], [StringLength(100)], [Range(1, 120)], and [EmailAddress] describe constraints once on the model, and both the model binder during POST processing and the Razor HTML helpers during rendering read the same attributes, so the rule is defined in exactly one place instead of being duplicated across controller logic and view markup.

🏏

Cricket analogy: It is like a single fielding restriction rule set in the tournament regulations—maximum five fielders outside the circle—that both the on-field umpire enforces during play and the broadcast graphics display automatically, rather than each party maintaining a separate copy of the rule.

Common Built-In Validation Attributes

MVC ships with a core set of attributes covering the majority of everyday validation needs: [Required] rejects null or empty values, [StringLength(max, MinimumLength = min)] bounds text length, [Range(min, max)] bounds numeric or date values, [RegularExpression(pattern)] enforces a custom pattern like a postal code format, and [Compare("Password")] checks that two fields match, commonly used for password confirmation fields. Each attribute also accepts an ErrorMessage property for a custom validation message, and the framework falls back to a generic default message if none is supplied, which is why unconfigured forms often show unhelpful text like 'The field Name is invalid.'

🏏

Cricket analogy: It is like a set of standard pitch-inspection checks—minimum grass coverage, maximum crack width, bounce consistency—each with its own named criterion, similar to how the ICC pitch report evaluates a venue like Eden Gardens before a Test match.

csharp
public class RegisterViewModel
{
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(50, MinimumLength = 2)]
    public string Name { get; set; }

    [Required]
    [EmailAddress(ErrorMessage = "Enter a valid email address.")]
    public string Email { get; set; }

    [Required]
    [Range(18, 100, ErrorMessage = "Age must be between 18 and 100.")]
    public int Age { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [Compare("Password", ErrorMessage = "Passwords do not match.")]
    public string ConfirmPassword { get; set; }
}

Client-Side Validation and Custom Attributes

When a view is rendered with @Html.EditorFor and unobtrusive client validation is enabled (via jquery.validate.unobtrusive.js), MVC emits data-val-* HTML5 attributes derived from the same Data Annotations, so the browser blocks form submission and shows inline errors before the request ever reaches the server. This client-side check is purely a usability convenience, not a security boundary, because a user can disable JavaScript or submit a raw HTTP request directly, so the server must always re-run ModelState.IsValid regardless of what the client already checked, and custom rules beyond the built-in attributes are added by implementing IValidatableObject or creating a class that inherits ValidationAttribute.

🏏

Cricket analogy: It is like a batting coach giving instant feedback in the nets before a match, which helps a player like Shubman Gill correct technique early, but the real, final judgment still happens out in the middle under the umpire's official decision on match day.

Client-side unobtrusive validation requires three script references in the correct order: jquery.js, jquery.validate.js, and jquery.validate.unobtrusive.js, along with <system.web><appSettings> or Web.config keys ClientValidationEnabled and UnobtrusiveJavaScriptEnabled both set to true (the default in modern templates).

Never trust client-side validation as your only defense. Always check ModelState.IsValid on the server inside every POST action, because client validation can be bypassed entirely by disabling JavaScript, using browser dev tools, or sending a crafted HTTP request with a tool like Postman.

  • Data Annotations declare validation rules once on the model using attributes like [Required], [StringLength], [Range], and [RegularExpression].
  • The same attributes drive both server-side ModelState validation and client-side unobtrusive JavaScript validation.
  • [Compare] validates that two fields, such as Password and ConfirmPassword, match.
  • Custom messages are set via the ErrorMessage property; otherwise a generic default message is shown.
  • Client-side validation is a usability feature only — always re-check ModelState.IsValid on the server.
  • Unobtrusive validation requires jquery.js, jquery.validate.js, and jquery.validate.unobtrusive.js loaded in order.
  • Custom validation logic beyond the built-in attributes is added via IValidatableObject or a custom ValidationAttribute subclass.

Practice what you learned

Was this page helpful?

Topics covered

#NETFramework#ASPNETMVCStudyNotes#MicrosoftTechnologies#DataAnnotationsAndValidation#Data#Annotations#Validation#Declarative#StudyNotes#SkillVeris