Take advantage of data annotations to decorate your models using attribute tags so that your application’s data definition can be managed in a single place. Credit: Metamorworks / Getty Images Data annotations (available as part of the System. ComponentModel. DataAnnotations namespace) are attributes that can be applied to classes or class members to specify the relationship between classes, describe how the data is to be displayed in the UI, and specify validation rules. This article talks about data annotations, why they are useful, and how to use them in our .NET Core applications. To work with the code examples provided in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here. Create a console application project in Visual Studio 2019 First off, let’s create a .NET Core Console Application project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new .NET Core Console Application project in Visual Studio. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed. Click Next. In the “Configure your new project” window shown next, specify the name and location for the new project. Click Create. This will create a new .NET Core console application project in Visual Studio 2019. We’ll use this project to work with data annotations in the subsequent sections of this article. Include the System. ComponentModel. DataAnnotations namespace To work with the code samples given in this article, you should include the System. ComponentModel. DataAnnotations namespace in your program. Note that attributes are used to specify metadata on a class or a property. The data annotation attributes can broadly be classified into the following: Validation attribute — Used to enforce validation rules on the properties of the entities Display attribute — Used to specify how the data should be displayed in the user interface Modeling attribute — Used to specify the relationship that exists between classes Data annotations attribute classes in C# The System.ComponentModel.Annotations namespace comprises several attribute classes that can be used to define metadata for your entity classes or data controls. The most commonly used attributes include the following: ConcurrencyCheck Key MaxLength Required StringLength Timestamp Data annotations example in C# Create the following class in a file named Author.cs in the console application we’ve created earlier. public class Author { [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "First Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string FirstName { get; set; } [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "Last Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string LastName { get; set; } [DataType(DataType.PhoneNumber)] [Phone] public string PhoneNumber { get; set; } [DataType(DataType.EmailAddress)] [EmailAddress] public string Email { get; set; } } The following code snippet illustrates how you can create an instance of the Author class and assign values to its properties. Author author = new Author(); author.FirstName = "Joydip"; author.LastName = ""; author.PhoneNumber = "1234567890"; author.Email = "joydipkanjilal@yahoo.com"; You can write the following code snippet in the Main method of the Program.cs file to validate your model. ValidationContext context = new ValidationContext(author, null, null); List<ValidationResult> validationResults = new List<ValidationResult>(); bool valid = Validator.TryValidateObject(author, context, validationResults, true); if (!valid) { foreach (ValidationResult validationResult in validationResults) { Console.WriteLine("{0}", validationResult.ErrorMessage); } } ValidationContext is the class that provides you the context where the validation should be done. The TryValidateObject static method of the Validator class returns true if the validation is successful, false otherwise. It also returns a list of ValidationResults that details all validations that have failed on the model. Finally, we’ve used a foreach loop to iterate the list of ValidationResults and display the error messages at the console window. The complete code listing is given below for your reference. public class Author { [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "First Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string FirstName { get; set; } [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "Last Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string LastName { get; set; } [DataType(DataType.PhoneNumber)] [Phone] public string PhoneNumber { get; set; } [DataType(DataType.EmailAddress)] [EmailAddress] public string Email { get; set; } } class Program { static void Main(string[] args) { Author author = new Author(); author.FirstName = "Joydip"; author.LastName = ""; //No value entered author.PhoneNumber = "1234567890"; author.Email = "joydipkanjilal@yahoo.com"; ValidationContext context = new ValidationContext (author, null, null); List<ValidationResult> validationResults = new List<ValidationResult>(); bool valid = Validator.TryValidateObject (author, context, validationResults, true); if (!valid) { foreach (ValidationResult validationResult in validationResults) { Console.WriteLine("{0}", validationResult.ErrorMessage); } } Console.ReadKey(); } } When you execute the program, you should see the following error message displayed at the console window: LastName is required Create a custom validation attribute in C# To create a custom validation attribute class, you should extend the ValidationAttribute base class and override the IsValid method as shown in the code snippet given below. [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class IsEmptyAttribute : ValidationAttribute { public override bool IsValid(object value) { var inputValue = value as string; return !string.IsNullOrEmpty(inputValue); } } The following code snippet illustrates how you can use the custom attribute to decorate the FirstName and LastName properties of the Author class. [IsEmpty(ErrorMessage = "Should not be null or empty.")] public string FirstName { get; set; } [IsEmpty(ErrorMessage = "Should not be null or empty.")] public string LastName { get; set; } Data annotations were introduced initially in .NET 3.5 as part of the System. ComponentModel. DataAnnotations namespace. Since then they have become a widely used feature in .NET. You can take advantage of data annotations to define data validation rules in a single place and thereby avoid having to re-write the same validation code again and again. In a future post here, we’ll look at how data annotation can be used in ASP.NET Core MVC applications to perform model validation. How to do more in C# When to use an abstract class vs. interface in C# How to work with AutoMapper in C# How to use lambda expressions in C# How to work with Action, Func, and Predicate delegates in C# How to work with delegates in C# How to implement a simple logger in C# How to work with attributes in C# How to work with log4net in C# How to implement the repository design pattern in C# How to work with reflection in C# How to work with filesystemwatcher in C# How to perform lazy initialization in C# How to work with MSMQ in C# How to work with extension methods in C# How to us lambda expressions in C# When to use the volatile keyword in C# How to use the yield keyword in C# How to implement polymorphism in C# How to build your own task scheduler in C# How to work with RabbitMQ in C# How to work with a tuple in C# Exploring virtual and abstract methods in C# Related content feature What is Rust? Safe, fast, and easy software development Unlike most programming languages, Rust doesn't make you choose between speed, safety, and ease of use. Find out how Rust delivers better code with fewer compromises, and a few downsides to consider before learning Rust. By Serdar Yegulalp Nov 20, 2024 11 mins Rust Programming Languages Software Development how-to Kotlin for Java developers: Classes and coroutines Kotlin was designed to bring more flexibility and flow to programming in the JVM. Here's an in-depth look at how Kotlin makes working with classes and objects easier and introduces coroutines to modernize concurrency. By Matthew Tyson Nov 20, 2024 9 mins Java Kotlin Programming Languages analysis Azure AI Foundry tools for changes in AI applications Microsoft’s launch of Azure AI Foundry at Ignite 2024 signals a welcome shift from chatbots to agents and to using AI for business process automation. By Simon Bisson Nov 20, 2024 7 mins Microsoft Azure Generative AI Development Tools news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks Resources Videos