21
NovServer Side Model Validation in MVC Razor
Server-Side Model Validation: An Overview
In this MVC Tutorial, we will see Server-Side Model Validation in MVC Razor. Server-side validations are required to ensure that received data is correct and valid. If the received data is valid then we do the further processing with the data. Server-side validations are very important before playing with the sensitive information of a user.
Read More: MVC Interview Questions and Answers
What is Server Side Model Validation?
Server-side validation must be done whether we validate the received data on the client side. The user could disable the script in his browser or do something else to bypass client-side validation. In this case, server-side validation must required to protect our data from dirty input.
Server-Side Model Validation Techniques
In MVC Razor, we can validate a model server side in the following two ways:
- Explicit Model Validation
- Model Validation with Data Annotations
1. Explicit Model Validation
Suppose, you want to validate the registration process of a user for which the Registration model and view are defined below:
RegistrationModel.cs
public class RegistrationModel
{
public string UserName { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public Country Country { get; set; }
public City City { get; set; }
public string Address { get; set; }
public string MobileNo { get; set; }
public bool TermsAccepted { get; set; }
}
public class Country
{
public int? ID { get; set; }
public string Name { get; set; }
}
public class City
{
public int? ID { get; set; }
public string Name { get; set; }
public int? Country { get; set; }
}
ExplicitServer.cshtml
@model Mvc4_Client_ServerSideValidation.Models.RegistrationModel
@{
ViewBag.Title = "Explicit Server Side Validation";
}
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script type="text/jscript">
$(function () {
$('#Country_ID').change(function () {
var id = $("#Country_ID :selected").val();
if (id != "") {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: '@Url.Action("CityList", "Home")',
data: { "mCountry": id },
dataType: "json",
success: function (data) {
var items = "";
$.each(data, function (i, city) {
items += "<option value='" + city.Value + "'>" + city.Text + "</option>";
});
$('#City_ID').html(items);
},
error: function (result) {
alert('Service call failed: ' + result.status + ' Type :' + result.statusText);
}
});
}
else
{
var items = '<option value="">Select</option>';
$('#City_ID').html(items);
} });
});
</script>
<h2>Explicit Server Side Validation</h2> @using (Html.BeginForm())
{
<fieldset>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName, new { maxlength = 50 })
@Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password, new { maxlength = 50, value = ViewBag.Selpwd })
@Html.ValidationMessageFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.ConfirmPassword)
@Html.PasswordFor(m => m.ConfirmPassword, new { maxlength = 50, value = ViewBag.Selconfirmpwd })
@Html.ValidationMessageFor(m => m.ConfirmPassword)
</li>
<li>
@Html.LabelFor(m => m.Country)
@Html.DropDownListFor(m => m.Country.ID, new SelectList(ViewBag.Country, "ID", "Name"), new { style = "width:310px" })
@Html.ValidationMessageFor(m => m.Country)
</li>
<li>
@Html.LabelFor(m => m.City)
@Html.DropDownListFor(m => m.City.ID, new SelectList(ViewBag.City, "ID", "Name"), new { style = "width:310px" })
@Html.ValidationMessageFor(m => m.City)
</li>
<li>
@Html.LabelFor(m => m.Address)
@Html.TextAreaFor(m => m.Address, new { maxlength = 200 })
@Html.ValidationMessageFor(m => m.Address)
</li>
<li>
@Html.LabelFor(m => m.MobileNo)
@Html.TextBoxFor(m => m.MobileNo, new { maxlength = 10 })
@Html.ValidationMessageFor(m => m.MobileNo)
</li>
<li>
@Html.CheckBoxFor(m => m.TermsAccepted) I accept the terms & conditions
@Html.ValidationMessageFor(m => m.TermsAccepted)
</li>
</ol>
<input type="submit" value="Submit" />
</fieldset>
}
Now let's see how we validate the model explicitly. To validate a model explicitly we need to validate received data within the action method as:
[HttpPost]
public ActionResult ExplicitServer(RegistrationModel mRegister)
{
//Write custom logic to validate RegistrationModel
if (string.IsNullOrEmpty(mRegister.UserName))
{
ModelState.AddModelError("UserName", "Please enter your name");
}
if (!string.IsNullOrEmpty(mRegister.UserName))
{
Regex emailRegex = new Regex(".+@.+\\..+");
if (!emailRegex.IsMatch(mRegister.UserName))
ModelState.AddModelError("UserName", "Please enter correct email address");
}
if (string.IsNullOrEmpty(mRegister.Password))
{
ModelState.AddModelError("Password", "Please enter password");
}
if (string.IsNullOrEmpty(mRegister.ConfirmPassword))
{
ModelState.AddModelError("ConfirmPassword", "Please enter confirm password");
}
if (string.IsNullOrEmpty(mRegister.ConfirmPassword) && string.IsNullOrEmpty(mRegister.ConfirmPassword))
{
if (mRegister.ConfirmPassword != mRegister.Password)
ModelState.AddModelError("ConfirmPassword", "Confirm password doesn't match");
}
if (mRegister.Country.ID == null || mRegister.Country.ID == 0)
{
ModelState.AddModelError("Country", "Please select Country");
}
if (mRegister.City.ID == null || mRegister.City.ID == 0)
{
ModelState.AddModelError("City", "Please select City");
}
if (string.IsNullOrEmpty(mRegister.Address))
{
ModelState.AddModelError("Address", "Please enter your address");
}
if (string.IsNullOrEmpty(mRegister.MobileNo))
{
ModelState.AddModelError("MobileNo", "Please enter your mobile no");
}
if (!mRegister.TermsAccepted)
{
ModelState.AddModelError("TermsAccepted", "You must accept the terms");
}
if (ModelState.IsValid)
{
return View("Completed");
}
else
{
ViewBag.Selpwd = mRegister.Password;
ViewBag.Selconfirmpwd = mRegister.ConfirmPassword;
BindCountry();
if (mRegister.Country != null)
BindCity(mRegister.Country.ID);
else BindCity(null);
return View();
}
}
How it works?
After running the project and navigating to the ExplicitServer page you will get the below page. When you press the submit button on this page then it will post the data to the server and the code written in ExplicitServer action will validate the input data. If input data is not valid then add an error to the model state by using the method AddModelError() as shown above.
When all the validation is passed then ModelState.IsValid returns true and you will be shown the Completed view as shown in Fig.
2. Model Validation with Data Annotations
The other and best way to validate a model is by using Data Annotations. Data Annotations was introduced with .Net 3.5 SP1. It has a set of attributes and classes defined in the System.ComponentModel.DataAnnotations assembly. Data Annotations allow us to decorate model classes with metadata. This metadata describes a set of rules used to validate a property.
In RegistrationModel.cs, I have defined one more model class RegistrationMetaModel by using data annotation for which the view is defined as below:
RegistrationModel.cs
public class RegistrationMetaModel
{
[Required(ErrorMessage = "Please Enter Email Address")]
[Display(Name = "UserName (Email Address)")]
[RegularExpression(".+@.+\\..+", ErrorMessage = "Please Enter Correct Email Address")]
public string UserName { get; set; }
[Required(ErrorMessage = "Please Enter Password")]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required(ErrorMessage = "Please Enter Confirm Password")]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Display(Name = "Country")] [ValidCountryAttribute(ErrorMessage = "Please Select Country")]
public Country Country { get; set; }
[Display(Name = "City")]
[ValidCityAttribute(ErrorMessage = "Please Select City")]
public City City { get; set; }
[Required(ErrorMessage = "Please Enter Address")]
[Display(Name = "Address")]
[MaxLength(200)]
public string Address { get; set; }
[Required(ErrorMessage = "Please Enter Mobile No")]
[Display(Name = "Mobile")]
[StringLength(10, ErrorMessage = "The Mobile must contains 10 characters", MinimumLength = 10)]
public string MobileNo { get; set; }
[MustBeTrue(ErrorMessage = "Please Accept the Terms & Conditions")]
public bool TermsAccepted { get; set; }
}
public class MustBeTrueAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value is bool && (bool)value;
}
}
public class ValidCountryAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (((Country)value).ID == null || ((Country)value).ID == 0)
return false;
else
return true;
}
}
public class ValidCityAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (((City)value).ID == null || ((City)value).ID == 0)
return false;
else
return true;
}
}
ServerMeta.cshtml
@model Mvc4_Model_ServerSideValidation.Models.RegistrationMetaModel
@{
ViewBag.Title = "Server Side Validation by Specifying Validation Rules Using Metadata";
}
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script type="text/jscript">
$(function ()
{
$('#Country_ID').change(function ()
{
var id = $("#Country_ID :selected").val();
if (id != "")
{
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: '@Url.Action("CityList", "Home")',
data: { "mCountry": id },
dataType: "json",
beforeSend: function () {
},
success: function (data) {
var items = "";
$.each(data, function (i, city) {
items += "<option value='" + city.Value + "'>" + city.Text + "</option>";
});
$('#City_ID').html(items);
},
error: function (result) {
alert('Service call failed: ' + result.status + ' Type :' + result.statusText);
}
});
}
else {
var items = '<option value="">Select</option>';
$('#City_ID').html(items);
}
});
});
</script>
<h2>Server Side Validation by Specifying Validation Rules Using Metadata</h2>
@using (Html.BeginForm())
{
<fieldset>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName, new { maxlength = 50 })
@Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password, new { maxlength = 50, value = ViewBag.Selpwd })
@Html.ValidationMessageFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.ConfirmPassword)
@Html.PasswordFor(m => m.ConfirmPassword, new { maxlength = 50, value = ViewBag.Selconfirmpwd })
@Html.ValidationMessageFor(m => m.ConfirmPassword)
</li>
<li>
@Html.LabelFor(m => m.Country)
@Html.DropDownListFor(m => m.Country.ID, new SelectList(ViewBag.Country, "ID", "Name", ViewBag.SelCountry), new { style = "width:310px" })
@Html.ValidationMessageFor(m => m.Country)
</li>
<li>
@Html.LabelFor(m => m.City)
@Html.DropDownListFor(m => m.City.ID, new SelectList(ViewBag.City, "ID", "Name", ViewBag.SelCity), new { style = "width:310px" })
@Html.ValidationMessageFor(m => m.City)
</li>
<li>
@Html.LabelFor(m => m.Address)
@Html.TextAreaFor(m => m.Address, new { maxlength =200 })
@Html.ValidationMessageFor(m => m.Address)
</li>
<li>
@Html.LabelFor(m => m.MobileNo)
@Html.TextBoxFor(m => m.MobileNo ,new { maxlength = 10 })
@Html.ValidationMessageFor(m => m.MobileNo)
</li>
<li>
@Html.CheckBoxFor(m => m.TermsAccepted) I accept the terms & conditions
@Html.ValidationMessageFor(m => m.TermsAccepted)
</li>
</ol>
<input type="submit" value="Submit" />
</fieldset>
}
Now let's see how we validate the model using data annotation. To validate a model explicitly we need to validate received data within the action method by checking ModelState.IsValid property. If it is false an error message will be shown automatically against each property of the model as shown below in Fig.
[HttpPost]
public ActionResult ServerMeta(RegistrationMetaModel mRegister)
{
if (ModelState.IsValid)
{
return View("Completed");
}
else
{
ViewBag.Selpwd = mRegister.Password;
ViewBag.Selconfirmpwd = mRegister.ConfirmPassword;
BindCountry();
if (mRegister.Country != null)
BindCity(mRegister.Country.ID);
else
BindCity(null);
return View();
}
}
How Does It Work?
After running the project and navigating to the Data Annotation-Server-Side page you will get the below page. When you press the submit button on this page then it will post the data to the server and the code written within ServerMeta action will validate the input data by checking ModelState.IsValid property. If input data is not valid then ModelState.IsValid will return false and show an error as shown below.
When all the validation is passed then ModelState.IsValid returns true and you will be shown the Completed view as shown in Fig.
Read More
- Custom Validation for Checkbox in MVC Razor
- Custom Validation for Cascading Dropdownlist in MVC Razor
- ASP.NET MVC Registration form with Validation
Summary
I hope you enjoyed the tricks while programming with MVC Razor. I would like to have feedback from my blog readers. Your valuable feedback, questions, or comments about this article are always welcome. Enjoy Coding..!