Hi everyone,
In the previous post, I explained you “How To Write A Real Time Chat Application In Only 5 Minutes! (Using SignalR)“. I mentioned about something which is; what SignalR is, how to use it, etc. We also saw what an amazing technology SignalR is. Now, We’re going to concern about useful attributes whichI have used for validation. Generally, they are used with properties in the classes.
What Are The Attributes
Attributes provide extended features of associating metadata. In other words, attributes are used for associated metadata such as, properties, methods, classes and so forth.
Using Attributes
In C#, you specify an attribute to place a property/class/etc, between square brackets ([]). In VB, an attribute is written between angle brackets (< >). The attribute is applied to an element and this attribute must be located just before its element, both of them could be on the same line.
Single Attribute:
public class User { [AttributeName] public string MyProperty { get; set; } }
Multiple Attributes(two ways)
First way:
public class User { [AttributeName1][AttributeName2] public string MyProperty { get; set; } }
Second way:
public class User { [AttributeName1,AttributeName2] public string MyProperty { get; set; } }
Technical Requirements
We’ll be using ASP.NET MVC 4 (Basic Template) on Visual Studio 2012 with C# to develop this example.
Beginning
There are some server side and client side techniques for validation inputs. We always need to validate inputs/fields such as username, email, birthdate, password, comparing password etc. However, the most important thing is that every input uses different validation type. So, you have to know what kind of validation you should use. On the other hand, only using client side functions for validation does not give perfect result while we’re developing web application.
Let’s Do It
#1 Step: Right Click to Models, then add a Class and name it “User”
#2 Step: Add Properties To User Class
public class User { public string username { get; set; } public string password { get; set; } public string comparePassword { get; set; } public string email { get; set; } public string birthdate { get; set; } public string registrationDate { get; set; } }
#3 Step: Right Click to Controller, then add a Controller and name it “Home”
#4 Step: Add View and Name it “Index”
#5 Step: Reference Script Libraries and Add Style File (between head tags)
We have to add script and css files below to use validation perfectly. We need css classes in the file(/Content/Site.css) to show errors as javascript functions are used to validate fields.
<head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link href="~/Content/Site.css" rel="stylesheet" /> <script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> </head>
#6 Step: Add User Class as Model to Index Page
This operation is also called “Model Validation” which we are going to do . So, We must assign a model to the page for validation.
@model TheDataAnnotationValidators.Models.User @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link href="~/Content/Site.css" rel="stylesheet" /> <script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> </head> <body> </body> </html>
#7 Step: Prepare the Index page
You generate page structure below automatically. Normally, we would like to create a TextBox, a Label, a DropDownList, a RadioButton, etc, one thing what you should do is to write this code: @Html.TextBox, @Html.Label, @Html.DropDownList, @Html.RadioButton. When you see a helper which contains “For” keyword after Helper name -such as @Html.TextBoxFor, @Html.LabelFor-, it means that it’s used for the “Model”. On the other hand, a ValidationMessageFor is used to show validation message for a related field.
@model TheDataAnnotationValidators.Models.User @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link href="~/Content/Site.css" rel="stylesheet" /> <script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> </head> <body> @using (Html.BeginForm()) { <fieldset> <legend>User</legend> <div class="editor-label"> @Html.LabelFor(model => model.username) </div> <div class="editor-field"> @Html.EditorFor(model => model.username) @Html.ValidationMessageFor(model => model.username) </div> <div class="editor-label"> @Html.LabelFor(model => model.password) </div> <div class="editor-field"> @Html.EditorFor(model => model.password) @Html.ValidationMessageFor(model => model.password) </div> <div class="editor-label"> @Html.LabelFor(model => model.comparePassword) </div> <div class="editor-field"> @Html.EditorFor(model => model.comparePassword) @Html.ValidationMessageFor(model => model.comparePassword) </div> <div class="editor-label"> @Html.LabelFor(model => model.email) </div> <div class="editor-field"> @Html.EditorFor(model => model.email) @Html.ValidationMessageFor(model => model.email) </div> <div class="editor-label"> @Html.LabelFor(model => model.birthdate) </div> <div class="editor-field"> @Html.EditorFor(model => model.birthdate) @Html.ValidationMessageFor(model => model.birthdate) </div> <div class="editor-label"> @Html.LabelFor(model => model.registrationDate) </div> <div class="editor-field"> @Html.EditorFor(model => model.registrationDate) @Html.ValidationMessageFor(model => model.registrationDate) </div> <p> <input type="submit" value="Sender" /> </p> </fieldset> @Html.ValidationSummary(true) } </body> </html>
#8 Step: Learning The Attributes
- Display: To change display name of a property name
- Required: To require a field
-
DataType: To define a field’s type
- RegularExpression: To validate a field using Regex Pattern
- StringLength: To specify a string’s character length
- Compare: To compare two fields like password and comparePassword
- Range: To limit values for a field
- DisplayFormat: To show display in a format you want
- CustomValidation: To validate new kind of validation that you want/need
- Remote: To use an action in controller to validate a field
#9 Step: Implementation
Display:You can apply one or more attributes to a class property. First of all, let’s organize all input labels as;
public class User { [Display(Name="Username")] public string username { get; set; } [Display(Name = "Password")] public string password { get; set; } [Display(Name = "Compare Password")] public string comparePassword { get; set; } [Display(Name = "Email")] public string email { get; set; } [Display(Name = "Birthdate")] public string birthdate { get; set; } [Display(Name = "Registration Date")] public string registrationDate { get; set; } }
It’s nice, isn’t it? Keep going…
Required: All fields except RegistrationDate field are required to fill blank.
ErrorMessage=if a user does not fill field which associated with attribute, ErrorMessage is used to show a customized validation message.
public class User { [Display(Name = "Username"), Required(ErrorMessage="You have to fill The Username field is required")] public string username { get; set; } [Display(Name = "Password"),Required] public string password { get; set; } [Display(Name = "Compare Password"),Required] public string comparePassword { get; set; } [Display(Name = "Email"),Required] public string email { get; set; } [Display(Name = "Birthdate"),Required] public string birthdate { get; set; } [Display(Name = "Registration Date")] public string registrationDate { get; set; } }
DataType: As you see, We used @Html.EditorFor for all fields. However, we have also an absolute requirement for password fields to show password char. We should decide which field is which kind of DataType.
public class User { [Display(Name = "Username"), Required(ErrorMessage = "You have to fill The Username field is required")] public string username { get; set; } [Display(Name = "Password"), Required, DataType(DataType.Password)] public string password { get; set; } [Display(Name = "Compare Password"), Required] public string comparePassword { get; set; } [Display(Name = "Email"), Required] public string email { get; set; } [Display(Name = "Birthdate"), Required] public string birthdate { get; set; } [Display(Name = "Registration Date")] public string registrationDate { get; set; } }
As we did for the password field, we add DataType to the comparePassword field.
RegularExpression: better known by general usage name RegEx, provides a match to a string of text using a pattern string which persists user to data input. This pattern can use different patterns like email, phone number, zip code, etc.
You can find several patterns on RegexLib.com, more information about RegularExpression.
A Sample Pattern String: “^[0-9a-zA-Z]+([0-9a-zA-Z]*[-._+])*[0-9a-zA-Z]+@[0-9a-zA-Z]+([-.][0-9a-zA-Z]+)*([0-9a-zA-Z]*[.])[a-zA-Z]{2,6}$”
public class User { [Display(Name = "Username"), Required(ErrorMessage = "You have to fill The Username field is required")] public string username { get; set; } [Display(Name = "Password"), Required, DataType(DataType.Password)] public string password { get; set; } [Display(Name = "Compare Password"), Required, DataType(DataType.Password)] public string comparePassword { get; set; } [Display(Name = "Email"), Required, RegularExpression("^[0-9a-zA-Z]+([0-9a-zA-Z]*[-._+])*[0-9a-zA-Z]+@[0-9a-zA-Z]+([-.][0-9a-zA-Z]+)*([0-9a-zA-Z]*[.])[a-zA-Z]{2,6}$", ErrorMessage = "Incorrect Email Format!")] public string email { get; set; } [Display(Name = "Birthdate"), Required] public string birthdate { get; set; } [Display(Name = "Registration Date")] public string registrationDate { get; set; } }
StringLength: allows a string between min and max characters length
public class User { [Display(Name = "Username"), Required(ErrorMessage = "You have to fill The Username field is required"), StringLength(10, ErrorMessage = "The {0} must be between {2} and {1} characters long.", MinimumLength = 6)] public string username { get; set; } [Display(Name = "Password"), Required, DataType(DataType.Password)] public string password { get; set; } [Display(Name = "Compare Password"), Required, DataType(DataType.Password)] public string comparePassword { get; set; } [Display(Name = "Email"), Required, RegularExpression("^[0-9a-zA-Z]+([0-9a-zA-Z]*[-._+])*[0-9a-zA-Z]+@[0-9a-zA-Z]+([-.][0-9a-zA-Z]+)*([0-9a-zA-Z]*[.])[a-zA-Z]{2,6}$", ErrorMessage = "Incorrect Email Format!")] public string email { get; set; } [Display(Name = "Birthdate"), Required] public string birthdate { get; set; } [Display(Name = "Registration Date")] public string registrationDate { get; set; } }
Compare: We always need to compare min two values which may be email to email or password to password. In this sample, we’ll compare ‘password’ field to ‘compare password’ field.
Attention: You must use a property’s csharp name – not displayName- in Compare Attribute
public class User { [Display(Name = "Username"), Required(ErrorMessage = "You have to fill The Username field is required"), StringLength(10, ErrorMessage = "The {0} must be between {2} and {1} characters long.", MinimumLength = 6)] public string username { get; set; } [Display(Name = "Password"), Required, DataType(DataType.Password)] public string password { get; set; } [Display(Name = "Compare Password"), Required, DataType(DataType.Password), Compare("password", ErrorMessage = "The Password does not match with the other")] public string comparePassword { get; set; } [Display(Name = "Email"), Required, RegularExpression("^[0-9a-zA-Z]+([0-9a-zA-Z]*[-._+])*[0-9a-zA-Z]+@[0-9a-zA-Z]+([-.][0-9a-zA-Z]+)*([0-9a-zA-Z]*[.])[a-zA-Z]{2,6}$", ErrorMessage = "Incorrect Email Format!")] public string email { get; set; } [Display(Name = "Birthdate"), Required] public string birthdate { get; set; } [Display(Name = "Registration Date")] public string registrationDate { get; set; } }
Range: Allow users for data input given range from one value to the other value.
Attention: Since we use integer value for Range, we changed the birthdate property’s name as “birthday“
[Display(Name = "Birthday"), Required, Range(1950, 1995,ErrorMessage = "Value for {0} must be between {1} and {2}")] public string birthday { get; set; }
<div class="editor-label"> @Html.LabelFor(model => model.birthday) </div> <div class="editor-field"> @Html.EditorFor(model => model.birthday) @Html.ValidationMessageFor(model => model.birthday) </div>
DisplayFormat: You can change how to display a field’s value easily.
Attention: Since we use DisplayFormat, we changed the registrationDate property’stype as “DateTime” instead of “string“
[Display(Name = "Registration Date")] public DateTime registrationDate { get; set; }
Attention 2: There is another change in the below. This is because, You just imagine that you want to update user information, you need to take current user information and then show the user who owner of these information is. Here, I just took instance of user class for this sample.
public ActionResult Index() { User myUser = new User(); myUser.registrationDate = DateTime.Now; return View(myUser); }
Attention 3: We want to show Registratin Date as “MM/dd/yy” format
[Display(Name = "Registration Date"), DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yy}")] public DateTime registrationDate { get; set; }
CustomValidation: The exist validation attributes are not inadequate for you to validate different type. You can simply use this one.
Attention: We create a class, named CustomAttributes, under models folder.
public class CustomAttributes { public static ValidationResult PasswordStrongTest(string value, ValidationContext validationContext) { if (value == null) return ValidationResult.Success; if (!Regex.IsMatch(value, @"(?=^.{6,10}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{":;'?/>.<,])(?!.*\s).*$")) return new ValidationResult("It expects at least 1 small-case letter, 1 Capital letter, 1 digit, 1 special character and the length should be between 6-10 characters. ", new List<string> { "password" }); return ValidationResult.Success; } }
Remote: You can use a method which returns ActionResult in a controller.
Attation: Here, we are going to apply this Attribute to username field. What we need to do is to add a method in the controller;
[HttpPost] public ActionResult CheckUserNameExist(string username) { List<string> usernames = new List<string>() { "mcansozeri", "billGates", "steveJobs" }; return Json(usernames.Find(x => x == username) == null); }
Result: I would like to demostrate all of the Attributes.
Download
Download using here.
Have a nice coding!
#1 by http://www.abortionreview.org/index.php/member/67626/ on March 5, 2013 - 12:25 am
That is very fascinating, You’re an overly skilled blogger. I’ve joined your feed and stay up
for looking for extra of your fantastic post.
Additionally, I’ve shared your website in my social networks