Remote Validation in MVC
- Model Class must have a namespace "System.Web.Mvc" where you have defined the property.
using System.Web.Mvc;
[Required(ErrorMessage = "E-mail is required")]
[RegularExpression(@"^[a-zA-Z0-9_\.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$", ErrorMessage = "Email is not valid")]
[StringLength(30, ErrorMessage = "Email must not be more than 30 char")]
[Remote("IsEmailAvailable", "User", ErrorMessage = "E-mail already in use")]
public string Email { get; set; }
- Make sure you have to implement IsEmailAvailable Action on the Controller.
[HttpGet]
public JsonResult IsEmailAvailable(string email)
{
// Check if the e-mail already exists
return Json(!db.Users.Any(x => x.Email == email), JsonRequestBehavior.AllowGet);
}
- Make sure you have added this js on View for client-side validation.
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
and also enable client-side validation from web.config
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Note:
Remote attribute only works when JavaScript is enabled. If the end-user, disables JavaScript on his/her machine then the validation does not work. This is because RemoteAttribute requires JavaScript to make an asynchronous AJAX call to the server-side validation method. As a result, the user will be able to submit the form, bypassing the validation in place. This why it is always important to have server-side validation.
In case when Javascript is disabled:
To make server-side validation work, when JavaScript is disabled, there are 2 ways
- Add model validation error dynamically in the controller action
method.
- Create a custom remote attribute and override IsValid() method.
Adding model validation error dynamically in the controller action method. Modify the Create action method that is decorated with [HttpPost] attribute as shown below.
[HttpPost]
public ActionResult Create(User user)
{
// Check if the Email already exists, and if it does, add Model validation error
if (db.Users.Any(x => x.Email == user.Email))
{
ModelState.AddModelError("Email", "Email already in use");
}
if (ModelState.IsValid)
{
db.Users.AddObject(user);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
At this point, disable JavaScript in the browser, and test your application. Notice that, we don't get client-side validation, but when you submit the form, server-side validation still prevents the user from submitting the form, if there are validation errors.
However, delegating the responsibility of performing validation, to a controller action method violates the separation of concerns within MVC. Ideally, all validation logic should be in the Model. Using validation attributes in MVC models should be the preferred method for validation.