2

I have run into an issue attempting to pass an array of objects to an MVC3 controller/action. I've found several discussions on the web (including here at SO) but none have solved my problem. Here is what I'm working with:

public class Person
{
   public Guid TempId { get; set; }
   public bool ReadOnly { get; set; }
   [Required(ErrorMessage = "Required")]
   public string Name { get; set; }
}

Here is what my controller action (currently, I've tried many variations) looks like:

[HttpGet]
public ActionResult AddPerson(List<Person> people)
{
    if (null != people)
    {
        foreach (var person in people)
        {
           Debug.WriteLine(person );
        }
     }
    return View();
}

I have tried numerous ways of structuring my jquery in order to call to action, but so far the only one I can get to work is if I manually encode the array of objects into the URL string like so:

var url = "AddPerson?people%5B0%5D.TempId=9FBC6EF8-67DB-4AB4-8FCE-5DFC0F2A69F9&people%5B0%5D.ReadOnly=true&people%5B0%5D.Name=Bob+Jones&people%5B1%5D.TempId=9FBC6EF8-67DB-4AB4-8FCE-5DFC0F2A6333&people%5B1%5D.ReadOnly=false&people%5B1%5D.Name=Mary+Jones #peopleDiv";
$("#peopleDiv").load(url, updatePeopleDiv);

The people%5B1%5D.ReadOnly=false is the encoded version of people[1].ReadOnly=false

I've tried other things such as:

var url = "AddPerson #peopleDiv";
var people = [];
people.push({'[0].TempId': '<valid guid>', '[0].ReadOnly': true, '[0].Name': 'Bob Jones' });
$("#peopleDiv").load(url, people, updatePeopleDiv); // nope
$("#peopleDiv").load(url, $.param(people, false), updatePeopleDiv); // nada
$("#peopleDiv").load(url, $.param(people, true), updatePeopleDiv); // nyet

I have also tried modifying the above by wrapping that people[] inside an object: var data = { arr: people } and then trying to send that data object various ways. All the ways (other than the one I got to work by manually encoding) result in one of three outcomes:

  1. No controller action called (mismatch between how it's defined and how I called it)
  2. Controller action called but param is null
  3. Controller action called, and correct number of object elements in the array BUT none of the actual values from those objects is transferred (so I have an array of objects all with default values).

Any suggestions?

Chris
  • 154
  • 1
  • 9
  • 2
    you don't want to pass complex objects by query string. you want to post those params. – Dave Alperovich Mar 28 '13 at 19:24
  • Dave - I agree, but as I explained (maybe poorly) is I could not get that to work and I had to resort to passing by query string. Can you show/point me to a working example? – Chris Mar 28 '13 at 19:36
  • What @DaveA said is correct, try passing it in a post. My suggestion is to create a JSON array and post it as a string to the controller, then deserialize it in the controller. If the controller action is not being hit then you're probably calling it wrong. For instance, your url contains a #peopleDiv. – lopezbertoni Mar 28 '13 at 19:57
  • 1
    This SO post [link](http://stackoverflow.com/questions/13242414/passing-a-list-of-objects-into-an-mvc-controller-method-using-jquery-ajax?rq=1) has a good example of the problem and solution...Pay close attention to the particular use of `JSON.Stringify` in the example because I believe you need this to fix your problem. – David Tansey Mar 28 '13 at 20:56

1 Answers1

5

Just set contentType to 'application/json' and use JSON.stringify().

$.ajax({
            contentType: 'application/json',
            type: 'POST',
            url: '/Controller/AddPerson',
            data: JSON.stringify({
                people: [
                    {
                      ReadOnly: false,
                      Name: 'Cristi'
                    },
                    {
                      ReadOnly: true,
                      Name: 'Matt'
                    }
                ]
            }),
            success: function (data) {
                $("#peopleDiv").html(data);
            },
            error: function () {
                console.trace();
            }
        });

Also, add/edit/delete requests should be done via POST.

[HttpPost]
public ActionResult AddPerson(List<Person> people)
{
    if (null != people)
    {
        foreach (var person in people)
        {
           Debug.WriteLine(person );
        }
     }
    return PartialView("viewname");
}
Cristi Pufu
  • 9,002
  • 3
  • 37
  • 43