views:

498

answers:

2

Hi All,

I'm just building my first MVC application and hitting a problem trying to perform a search using AJAX/JSON. The problem seems to be that the JSON returned by my controller is not an array meaning that I can't use jQuery's $.each method to iterate over my items. I'm trying to search for a user by e-mail address.

I've got a SearchController class with the following method:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SearchByEmail(string searchString)
{
  var users = new List<jsonUser>();
  foreach (I_User u in _rep.SearchByEmail(searchString))
  {
    users.Add(new jsonUser()
    {
      EmailAddress = u.EmailAddress,
      FirstName = u.Firstname,
      LastName = u.Surname,
      UserName = u.Username
    });
  }
  return Json(users);
}

Which fires correctly and returns something which looks, to me anyway, like a JSON array:

[{"EmailAddress":"[email protected]","UserName":"[email protected]","FirstName":"Foo","LastName":"Bar"}]

And then in my page, I've got the following code:

$("#search").click(function(evt) {
    var emailsearch = jQuery.trim($("#email").val());
    $.post("/Search/SearchByEmail", { searchString: emailsearch },
        function(Users) {
            $("#jsonlist").text(Users); //Added to check what JSON returns.
            alert($.isArray(Users)); //Added to work out if jQuery thinks this is an array!
            $.each(Users, function() {
                //Do stuff on each user item
            });
        });
    });
});

By adding the commented lines above, I've established that this function is getting a sensible result (the JSON posted above) but that it doesn't think this is an array. As such, $(this) in the $.each loop is undefined.

I've borrowed large chunks of this from the NerdDinner application, and really can't see what the difference is. Any suggestions greatly appreciated!

+1  A: 

I think you'll need to eval() the response to get it correct. Try something like:

$("#search").click(function(evt) {
    var emailsearch = jQuery.trim($("#email").val());
    $.post("/Search/SearchByEmail", { searchString: emailsearch },
        function(data) {
            $("#jsonlist").text(data); //Added to check what JSON returns.
            Users = eval( '(' + data + ')' );
            alert($.isArray(Users)); //Added to work out if jQuery thinks this is an array!
            $.each(Users, function() {
                //Do stuff on each user item
            });
        });
    });
});
landyman
That doesn't seem to help - any idea why that should be the case? I thought eval() just executed whatever argument is passed - is JSON executable?
Jon Artus
eval() will parse a properly formatted string into a json object literal
+3  A: 

If you're returning JSON have you tried adding the relevant data type parameter to the arguments of your $.post call?

$.post("/Search/SearchByEmail", 
       { searchString: emailsearch }, callback, "json");

The post will usually default to Html or text so it won't do the eval required to "deserialize" the post body.

sighohwell
That did the trick - gave me a headache working it out, since my debug call $("#jsonlist").text(Users); started to fail once Users was an object rather than a string!
Jon Artus