MSDN Documentation

Data Annotations in .NET

Data Annotations provide a powerful mechanism in .NET to describe the meaning and behavior of data models. They allow you to declarative associate metadata with properties, classes, and parameters, influencing aspects like validation, display, and data binding.

These attributes are primarily found in the System.ComponentModel.DataAnnotations namespace and are widely used in frameworks like ASP.NET MVC, ASP.NET Core, and Entity Framework.

Common Data Annotations

Data Annotations can be broadly categorized into two main types:

Validation Attributes

These attributes enforce rules on data. When a model is validated, any validation attributes present are checked, and if the data doesn't meet the criteria, validation errors are generated.

[Required]

Indicates that a data member must have a value. It checks for null or empty strings (for string types).

Example

[Required(ErrorMessage = "The Name field is required.")]
public string Name { get; set; }

[StringLength]

Validates that the length of a string value is within a specified range.

Example

[StringLength(100, ErrorMessage = "The Maximum length is 100 characters.")]
public string Description { get; set; }

[Range]

Validates that a data member's value falls within a specified range.

Example

[Range(1, 10, ErrorMessage = "The value must be between 1 and 10.")]
public int Quantity { get; set; }

[RegularExpression]

Validates a data member against a regular expression pattern.

Example

[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$", ErrorMessage = "Invalid characters in name.")]
public string ProductName { get; set; }

[Compare]

Compares one data member to another. Commonly used for password confirmation.

Example

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

[EmailAddress]

Validates that a string is a valid email address format.

Example

[EmailAddress]
public string Email { get; set; }

[Url]

Validates that a string is a valid URL format.

Example

[Url]
public string Website { get; set; }

[Phone]

Validates that a string is a valid phone number format.

Example

[Phone]
public string PhoneNumber { get; set; }

[DataType]

Specifies the type of a data member, aiding in UI rendering and validation. It's not a validation attribute itself but suggests how to interpret the data.

Example

[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }

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

Metadata Attributes

These attributes influence how properties are displayed or represented in the UI and other contexts, without enforcing validation rules.

[Display]

Specifies properties for displaying data fields, such as their name, group, and order.

Example

[Display(Name = "Product Name", GroupName = "Details", Order = 1)]
public string Name { get; set; }

[DisplayName]

A simpler way to set the display name for a property.

Example

[DisplayName("User's Email Address")]
public string Email { get; set; }

[DisplayFormat]

Specifies the data format for displaying a data member.

Example

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime OrderDate { get; set; }

[ScaffoldColumn]

Indicates whether a data member should be included in scaffolding operations (e.g., in generated views).

Example

[ScaffoldColumn(false)]
public int InternalId { get; set; }

Creating Custom Data Annotations

You can extend the functionality of data annotations by creating your own custom attributes. To do this, you typically derive from the ValidationAttribute class and override the IsValid method to implement your custom validation logic.

Example Outline

using System.ComponentModel.DataAnnotations;

public class MyCustomValidationAttribute : ValidationAttribute
{
    public MyCustomValidationAttribute() : base("The field value is invalid.") {}

    public override bool IsValid(object value)
    {
        // Implement your custom validation logic here
        if (value is string stringValue)
        {
            return !string.IsNullOrWhiteSpace(stringValue) && stringValue.Length > 5;
        }
        return false;
    }
}

Usage Scenarios

Data Annotations are incredibly versatile and are used in numerous scenarios:

By leveraging Data Annotations, you can write more robust, maintainable, and expressive .NET applications.