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 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos