代码改变世界

MVC JSON - JsonResult and jQuery

2010-02-21 09:22  AnyKoro  阅读(3042)  评论(1编辑  收藏  举报

The latest release of the MVC framework provides the JsonResult for Controller actions.  I was surprised that I did not find a weatlh of examples for usage so I figured it shouldn't be too hard to get a decent example going.  It turns out, it was even easier than I anticipated.  I wanted to create an example where I would invoke an AJAX call to dynamically populate a dropdown list. 

jQuery has recently received a huge surge of interest of the ASP.NET MVC community so I've been getting up to speed on it myself.  I am quickly turning into a true believer and I've been impressed not only with how few lines of javascript it takes me to get things done but also how (relatively) easy it was to learn.  In addition to numerous examples on the jQuery web site I also recommend jQuery In Action.

Getting an AJAX request with jQuery and JSON in MVC is actually pretty simple.  The first step is to have a Controller action that returns a JsonResult:

   1:  public JsonResult GetStateList()
   2:  {
   3:      List<ListItem> list = new List<ListItem>() {
   4:          new ListItem() { Value = "1", Text = "VA" },
   5:          new ListItem() { Value = "2", Text = "MD" },
   6:          new ListItem() { Value = "3", Text = "DC" }
   7:      };
   8:      return this.Json(list);
   9:  }

Here I'm using the System.Web.Mvc.ListItem class (which is used as items in the SelectList) to simply return a contrived list of US states to populate a dropdown list.  All I have to do is call the Json() method passing in my object and it will automatically be serialized to JSON.  When the request is made the AJAX call can be seen in the Web Development Helper which is an invaluable tool to any AJAX development:

Notice the "application/json" in the request header and the textual representation of the JSON that is being returned from my JSON controller action.

The jQuery to make this happen is quite succinct:

   1:  <script type="text/javascript">
   2:  $(function() {
   3:      $('#btnFillList').click(function() {
   4:          $.getJSON("/Home/GetStateList", null, function(data) {
   5:              $("#stateList").fillSelect(data);
   6:          });
   7:       });
   8:       
   9:       $('#btnClearList').click(function() {
  10:          $("#stateList").clearSelect();
  11:       });
  12:  });
  13:  </script>

Notice on line #4 the use of the $.getJSON() jQuery method.  Then I've simply written a re-usable jQuery method called fillSelect() which will work on the JSON format returned by the ListItem class returned by my controller action:

   1:  $.fn.clearSelect = function() {
   2:      return this.each(function() {
   3:          if (this.tagName == 'SELECT')
   4:              this.options.length = 0;
   5:      });
   6:   } 
   7:   
   8:  $.fn.fillSelect = function(data) {
   9:      return this.clearSelect().each(function() {
  10:          if (this.tagName == 'SELECT') {
  11:              var dropdownList = this;
  12:              $.each(data, function(index, optionData) {
  13:                  var option = new Option(optionData.Text, optionData.Value);
  14:                  
  15:                  if ($.browser.msie) {
  16:                      dropdownList.add(option);
  17:                  }
  18:                  else {
  19:                      dropdownList.add(option, null);
  20:                  }
  21:              });
  22:          }
  23:      });
  24:   }

On line #13 above you'll see the strongly-typed "Text" and "Value" properties that I have the luxury of using because of the native JSON serialization into objects.

The complete code sample can be downloaded here.  It's barely 50 lines of code in all.