February 21, 2009

JavaScript Arrays via JQuery Ajax to an Asp.Net WebMethod

Long title, but this is a problem that has haunted me for a while now.  I have an Asp.Net WebMethod that takes a List/IEnumerable/Array of stuff as a parameter, how do I send that stuff to that method using the JQuery Ajax method.

Now, without having to reinvent the wheel, do check out David Ward's articles on JQuery and Asp.Net WebMethods for a primer on how this is done.

But one item not mentioned is how to update methods that take lists.

If you want to know why this is hard, take a look at this sample.  If you have a web method that looks like this:

   1: [WebMethod]


   2: public void SendName(string firstName, string lastName)


   3: {


   4:     


   5: }




You are going to call it with code like this:





   1: $.ajax({


   2:   type: "POST",


   3:   url: "WebService.asmx/SendName",


   4:   data: "{'firstName':'Chris','lastName':'Brandsma'}",


   5:   contentType: "application/json; charset=utf-8",


   6:   dataType: "json",


   7:   success: function(msg) {


   8:   }


   9: });




If you are still wondering where this issue is, look at line 4 of the second sample there.  




data: "{'firstName':'Chris','lastName':'Brandsma'}",




The data that is being passed to the web method has to be converted to string first.  And a JSON compliant string.  Now, while there is a way to take a JSON string and turn that into functioning JavaScript code (via the eval method), there is no built in "turn this JavaScript object into a JSON string for me, m'kay".  For simple data this is no problem, but for complex data this is a daunting task.



But there is a way.



Enter JSON2.js by the most excellent Douglas Crockford (go check out his book, JavaScript the Good Parts) who is one of the for-most luminaries on JavaScript these days.



JSON2.js gives you a method called JSON.stringify. Which takes an object and returns a string.  All this in a class that can be minified to less than 2.5K.



Now, lets put this to work.



I'm going to create a new WebMethod:





   1: [WebMethod] 


   2: public void SendValues(List<string> list)


   3: {


   4:     


   5: }




Here is my JQuery code:





   1: var list = ["a", "b", "c", "d"];


   2: var jsonText = JSON.stringify({ list: list });


   3:  


   4: $.ajax({


   5:   type: "POST",


   6:   url: "WebService1.asmx/SendValues",


   7:   data: jsonText,


   8:   contentType: "application/json; charset=utf-8",


   9:   dataType: "json",


  10:   success: function() { alert("it worked"); },


  11:   failure: function() { alert("Uh oh"); }


  12: });




And it works!  If you are worried that I'm sending too simple an object here (a simple list of strings in this example), I have tested this with much more complex object types as well, and it still works wonderfully.

No comments: