Data integrity

While working on any application, it is very important to design it in such a way that it handles all scenarios, or at least provides user-friendly messages to users on what went wrong. We have already learned about exception handling in Chapter 7, Implementing Exception Handling, which can be handy in such scenarios. 

While working on a database or distributed applications, data integrity plays a vital role. 

Data integrity applies differently in different scenarios:

  • For example, if you are creating an application and storing user information in a table, one of the principles you may adopt might be to not maintain duplicate users in the table so that they are uniquely identifiable. This is termed entity integrity.
  • In a scenario where you are collecting demographic information, you may allow certain values, or ranges of values, in specific fields. This is termed domain integrity. In other words, you are making sure that the data entered in each record/entity is valid.
  • There may be a scenario where you have to enter data into multiple tables with a parent-child relationship. In such cases, your application should maintain these relationships while saving information to the database. This is called referential integrity.
  • Last but not least, in a business scenario, in order to achieve the desired outcome based on a business process, your application may enforce certain constraints. This is called user-defined integrity, or business-defined integrity.

There are many real-world examples. These include any eCommerce applications or any banking applications. How critical is it to validate and control input and program flow? In a banking application, what would happen in the event of a power outage? In an eCommerce application, how would a shopping cart be maintained between multiple sessions, when the user closes their browser, or in the event that a clean-up job kicks in?

Many of these data integrity options are available in the latest databases and frameworks, which enable us to utilize these options to validate and control the flow of our program.

One of the ways to validate data is to use the data annotations assembly, which is available in .NET Framework 3.5 and above. Data annotations talk about adding more information about an attribute or property in a class. You can use data annotations by referring to the System.ComponentModel.DataAnnotations namespace. These data annotations fall into three categories:

  • Validation attributes
  • Display attributes
  • Modeling attributes

Each of these attributes is used for a specific purpose: validation attributes enforce the validation of data; display attributes are used as display labels on the user interface, and modeling attributes represent the recommended use of the relevant attribute.

In the following class, we will reference System.ComponentModel.DataAnnotations and use validating attributes, display attributes, and modeling attributes on the three available properties: 

using System;
using System.ComponentModel.DataAnnotations;

namespace Chapter11
{
public class Student
{
[Required(ErrorMessage = "Fullname of the student is
mandatory")]
[StringLength(100,MinimumLength =5,ErrorMessage ="Name should
have minimum of 5 characters")]
[DataType(DataType.Text)]
public string FullName { get; set; }

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

[DataType(DataType.Date)]
[Display(Name ="Date of Birth")]
public DateTime DOB { get; set; }
}
}

On the name property, we have a required field attribute and string length restrictions as validation attributes. The data type set to text is a data modeling attribute that tells the system that the name attribute only accepts text values. On the DOB property, we have a display attribute. However, display properties can be used in either ASP.NET applications or WPF applications.

Now, we create an instance of the Student class and try to validate its data. Data annotations help us to define ValidationContext; when an object is validated, ValidationResult will be returned, which consists of all properties and their respective error messages. While defining properties in the Student class, we added attributes with messages. When ValidationContext returns results, it returns each of these properties with their respective attributes and messages:

Student st = new Student();
st.FullName = "st1";
st.EmailAddress = "st@st";
st.DOB = DateTime.Now;

ValidationContext context = new ValidationContext(st, null, null);
List<ValidationResult> results = new List<ValidationResult>();
bool valid = Validator.TryValidateObject(st, context, results, true);
if (!valid)
{
foreach (ValidationResult vr in results)
{
Console.Write("Student class Property Name :{0}",
vr.MemberNames.First());
Console.Write(" :: {0}{1}", vr.ErrorMessage,
Environment.NewLine);
}
}

When you create a ValidationContext instance, we use the constructor that takes three parameters. These are as follows:

  • An instance of an object that we want to validate
  • An object that implements the IServiceProvider interface, which means that you need to create an instance using the GetService method
  • A dictionary of a key/value pair to consume

Also, while trying to validate an object, we passed true as the last parameter, which represents the validation of all properties of the object.

When you execute the program, you should see the following output. The student's name should have a minimum of five characters and the email address should be in a valid format:

Student class Property Name :FullName :: Name should have minimum of 5 characters
Student class Property Name :EmailAddress :: The EmailAddress field is not a valid e-mail address.
Press any key to exit.

In the next section, we will look at the different features available in C# to validate our data.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.128.145