3

Most of my model is populated using $('form').serializeArray(), however an array of objects that form a paged grid need to be populated from its manager. For example:

public JsonResult SubmitForm(MyViewModel input)
{

...

public class MyViewModel
{
  [Display(Name = "Name")]
  public string GridName { get; set; }

  [Display(Name = "Description")]
  public string GridDescription { get; set; }

  public GridRow[] GridRows { get; set; }

The name and description would be picked up by serializeArray(), no issues there. If the GridRow is a string[], then it accepts me simply pushing multiple instances to it into the serialized array that jquery made:

var data = $('form').serializeArray();
for (var i in gridData) {
   data.push({ name: 'GridRows', value: gridData[i].id });
}
$.ajax({
   type: "POST",
   url: '/Central/Results/SubmitForm',
   dataType: "json",
   data: data,

This way I can at least get an array of the IDs. However, it does not allow me to push the entire object into it (gridData[i]) when I want to populate the proper data type. I always get a null value when it reaches the controller.

Any idea how I need to handle the data in order for MVC to populate the model correctly? Thanks.

2
  • If you're sending multiple rows, then I'd say you're sending multiple models. You'd need to change your controller signature to public JsonResult SubmitForm(IEnumerable<MyViewModel> input) Commented Nov 14, 2012 at 17:16
  • There is only 1 name and description in the model, but many rows. So its a many models inside a model. Commented Nov 15, 2012 at 9:54

2 Answers 2

1

I'm pretty sure this is related to having to set the traditional option to true in your Ajax post. jQuery handles arrays a little differently than you'd expect, in terms of when they are posted to MVC controller actions.

So do this:

$.ajax({
   type: "POST",
   url: '/Central/Results/SubmitForm',
   dataType: "json",
   traditional: true,
   data: data,
   ...

See this answer for more details.

Sign up to request clarification or add additional context in comments.

Comments

0

Turns out just need to add a line and property reference, and add each variable separately.

        for (var i in gridData) {
           for (var j in gridData[i]) {
              data.push({ name: 'GridRows[' + i + '].' + j, value: gridData[i][j] });
           }
        }

Edit: Just thought I'd post my updated helper method I wrote a while ago for this.

function serializeArray(obj, data, name) {
   /// <summary>Turns an object into an MVC standard array of values </summary>
   /// <param name="obj" type="Object">Object to serialise (required)</param>
   /// <param name="data" type="Array">Array to append data to end of (optional)</param>
   /// <param name="name" type="String">Name prefix for all entries (optional/ignore)</param>

   if (!data || !(data instanceof Array)) {
      data = [];
   }
   if (obj instanceof Array) {
      if (!name) {
         throw "Need an object name when converting an array";
      }
      for (var index = 0; index < obj.length; index++) {
         data = serializeArray(obj[index], data, name + '[' + index + ']');
      }
   } else if (obj instanceof Object) {
      for (var property in obj) {
         if (obj.hasOwnProperty(property)) {
            data = serializeArray(obj[property], data, name ? (name + '.' + property) : property);
         }
      }
   } else {
      data.push({ name: name, value: obj });
   }
   return data;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.