Thursday, December 2, 2010

Easy Ajax with ASP.NET MVC and Jquery

One of the reasons I love Asp.net MVC and Jquery is it makes client side coding so easy.  Here is a good example.  Lets say I want to have a html select control that updates automatically when it’s changed
First we build a Controller that has an action to output our view and an action to accept posts
   1: [HandleError]
   2: public class HomeController : Controller
   3: {
   4:     public ActionResult Index()
   5:     {
   6:         UserModel userModel = new UserModel(){UserId = 1,Type = UserTypes.User};
   7:  
   8:         return View(userModel);
   9:     }
  10:  
  11:     [AcceptVerbs(WebRequestMethods.Http.Post)]
  12:     public ActionResult UpdateUserType(UpdateUser input)
  13:     {
  14:         var result = new {Succss = true, Message = "Updated"};
  15:         return Json(result);
  16:    }
  17: }
notice UpdateUserType() has the attribute “[AcceptVerbs(WebRequestMethods.Http.Post)]” this forces it to only allows posts, also it takes a complex type, in this case a class of type UpdateUser.
Here is a quick over view of the model objects we are going to be using
   1: public class UserModel
   2: {
   3:     public int UserId { get; set; }
   4:     public UserTypes Type { get; set; }
   5: }
   6:  
   7: public enum UserTypes
   8: {
   9:     User = 1,
  10:     PowerUser = 2,
  11:     Admin = 3
  12: }
  13:  
  14: public class UpdateUser
  15: {
  16:     public int UserId { get; set; }
  17:     public UserTypes Type { get; set; }
  18: }
one of the nice this is that MVC takes care of the mapping and casting for us as you’ll see in a second.
The view is a very simple and strongly typed for the UserModel, first build the select control
   1: <select name="SelectUserType" onchange="UpdateUserType(this,<%=Model.UserId%>)">
   2:     <%foreach (UserTypes item in Enum.GetValues(typeof(UserTypes)).Cast<UserTypes>())
   3:     {
   4:             if(item ==  Model.Type)
   5:             {
   6:                 %><option selected="selected" value="<%=((int)item).ToString() %>"><%=item.ToString() %></option><%
   7:             }
   8:             else
   9:             {
  10:                 %><option value="<%=((int)item).ToString() %>"><%=item.ToString() %></option><%
  11:             }
  12:     } %>
  13: </select>
this loops through the UserTypes Enum to populate the select control and selects the value that’s selected in the view Model and we add an onchange that points to a javascript function that we pass the control and the UserId from the model into.
Next we add the javascript function(fyi this requires Jquery)
   1: <script type="text/javascript">
   2:     function UpdateUserType(sender, userId) {
   3:         var model = { UserId: userId, Type: sender.value };
   4:         $.post("/home/UpdateUserType",
   5:             model,
   6:            function (data) {
   7:  
   8:                alert("Was Successful: " + data.Succss);
   9:                alert("Message: " + data.Message);
  10:            });
  11:     }
  12: </script>
First we build a JSON object where the property names need to match the properly names in UpdateUser, Asp.net MVC needs this for mapping, and then we use Jquery $.post passing in the action URL, the JSON object we just built, and a javascript function to handle the returned data and your done.

A quick and easy way to add Ajax to any control and as always here is a link to the demo project http://bob-the-janitor-sample-code.googlecode.com/svn/trunk/ajaxMadeEasy/