Saturday, 7 April 2012

Implemeting Remote Validation ASP.NET MVC3

I have finally found some time to look at implementation of Remote Validation in ASP.NET MVC3

Definition of a entity DummyUser

public class DummyUser
    {
        [Required]
        [StringLength(6, ErrorMessage = "User name has to be longer than 6 characters.")]
        public string UserName { getset; }
 
        public string Name { getset; }
 
        public string Surname { getset; }
 
        public string Age { getset; }
    }

In Home controller I have created basic Create function. and the view as is displayed

    /// <summary>
    /// Default controller for remote validation.
    /// </summary>
    public class HomeController : Controller
    {
        /// <summary>
        /// Creates new dummy user.
        /// </summary>
        /// <returns> 
        /// View for creating new dummy user. 
        /// </returns>
        [HttpGet]
        public ActionResult Create()
        {
            return View(new DummyUser());
        }
    }

And generate new view : Create for entity.


Update Global.asax to start on this action as:

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            routes.MapRoute(
                "Default"// Route name
                "{controller}/{action}/{id}"// URL with parameters
                new { controller = "Home"
                      action = "Create"
                      id = UrlParameter.Optional } // Parameter defaults
            );
        }


As next step we have to make sure that web.config has set up remote validation.
Which is done in section of App Settings.

 <appSettings>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>


Now we have set up everything to start implementing remote validation.

We will add new attribute to UserName.
The attribute "Remote"  uses the jQuery validation plug-in. Read more about remote attribute
 Where we will define action and controller in order [Remote("Action","Controller")]

  public class DummyUser
    {
        [Required]
        [StringLength(6, ErrorMessage = "User name has to be longer than 6 characters.")]
        [Remote("ValidUserName","HomeValidation")]
        public string UserName { getset; }
 
        public string Name { getset; }
 
        public string Surname { getset; }
 
        public string Age { getset; }
    }



Now we need to Create our validation controller.
The recommendation is to create separate validation controller to separate logic from actions and validation, but it is not a rule and you can put your validation into same controller.
In my case i will be using HomeValidationController for this example

    /// <summary>
    /// Home validation controller with no output cache and disabled storing values.
    /// </summary>
    [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
    public class HomeValidationController : Controller
    {
        /// <summary>
        /// Valids the name of the user.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <returns>Result validation</returns>
        public JsonResult ValidUserName(string userName)
        {
            if (!string.IsNullOrEmpty(userName))
            {
                // we can allow get because there is no data saving
                return Json(trueJsonRequestBehavior.AllowGet);
            }
 
            return Json(falseJsonRequestBehavior.AllowGet);
        }
    }

Now when you start typing into the user name selection you will see request going to validation controller and hitting action in your controller.



The best part on this validation is that you do not have to modify anything in your view and this will just work. That's what i call magic:)