3

Good morning all!

I have the following object in my C# MVC application

public class FamilyMember 
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string Age { get; set; }
   public string Relationship { get; set; }
}

And also I have a object that contains a collection of the above class

public class Authorization {
   public ICollection<FamilyMember> FamilyMembers { get; set; }
}

Now all of this information is displayed on a View using a loop:

<ul class="family-list small-text" id="family-list">
@for (int i = 0; i < familySize; i++)
{
    var member = Model.FamilyMembers.ElementAt(i);
    <li class="family-member">
        <label style="display: none;" for="FirstName" class="grey-text family-label">First Name:</label>
        <input style="display: none;" type="text" class="family-member-input" id="FirstName" name="FamilyMember.FirstName" value="@member.FirstName" />
        <label style="display: none;" for="LastName" class="grey-text family-label">Last Name:</label>
        <input style="display: none;" type="text" class="family-member-input" id="LastName" name="LastName" value="@member.LastName" />
        <label style="display: none;" for="Age" class="grey-text family-label">Age:</label>
        <input style="display: none;" type="text" class="family-member-input" id="Age" name="Age" value="@member.Age" />
        <label style="display: none;" for="Relationship" class="grey-text family-label">Relationship:</label>
        <input style="display: none;" type="text" class="family-member-input" id="Relationship" name="Relationship" value="@member.Relationship" />
    </li>
}

Where @familySize is the Count of the FamilyMember collection.

Now there's a button on this view called Save that, after clicking, serializes the above list, among more input elements, using the jQuery .serialize() method. The output from this method is then sent to an AJAX call which calls out to an action method I've set up in the MVC project:

var saveConfirmed = function () {
    saveTransfereeAjax(transfereeForm.serialize(), saveTransfereeSuccess, saveTransfereeFailure);
};

var saveTransfereeAjax = function (data, success, error) {
    console.log(data);
    bootbox.dialog({
        message:
            '<div class="text-center"><img src="/Content/Images/load-spinner.gif" alt="loader" /> <p>Processing...</p></div>'
    });
    $.ajax({
        data: data,
        dataType: "text",
        type: "POST",
        url: "/api/savetransferee",
        success: success,
        error: error
    })
};

Where transfereeForm is the form on my view that I'm looking to serialize.

And here is the action method that is being POSTed to by the AJAX call.

public IHttpActionResult Save(Authorization authorization)
{
    //process authorization
}

Once I hit the action method, everything in the form seems to have serialized correctly, though not the members of the FamilyMember collection.

Is there any specific name attributes I need to have for each FamilyMember object's properties that are inside my view that would allow for each to be serialized into the FamilyMember collection? For example:

<input type='text' name='FamilyMember[i].FirstName' id='FamilyMember[i].FirstName' value='@member.FirstName' />

Where i represents the current index of the FamilyMember collection I'm iterating through.

Delfino
  • 967
  • 4
  • 21
  • 46

1 Answers1

1

I believe you will get the correct ID's and names if you use the HTML helpers. Also you have to use array instead of collection:

 public FamilyMember[] FamilyMembers { get; set; }

@for (int i = 0; i < Model.FamilyMembers.Length; i++) { 
        <li class="family-member">
          @Html.TextBoxFor(m => Model.FamilyMembers[i].FirstName, new {style = "display:none;"})
        </li>
      }

This would result in code:

<input id="FamilyMembers_0__FirstName" name="FamilyMembers[0].FirstName" style="display:none;" type="text" value="Name0">

Witch would result in this serialized value: FamilyMembers%5B0%5D.FirstName=Name0&FamilyMembers%5B1%5D.FirstName=Name1&FamilyMembers%5B2%5D.FirstName=Name2

Also this might be better serialized as json using serializeArray, have a look at this question: Convert form data to JavaScript object with jQuery

EDIT: here is how you could do it with serializeArray and keep using iCollection

First you need to set the name correctly.

 @{ var i = -1;}
    <ul class="family-list small-text" id="family-list">
      @foreach (var familyMembers in Model.FamilyMembers)
      {
        i++;
        <li class="family-member">
          @Html.TextBoxFor(m => familyMembers.Age, new {Name = "familyMembers[" + i + "].Age", style="display:none;" })
        </li>
      }
    </ul>

Then you need to serialize this as JSON, and post it as JSON

function objectifyForm(formArray) {//serialize data function
  var returnArray = {};
  for (var i = 0; i < formArray.length; i++){
    returnArray[formArray[i]['name']] = formArray[i]['value'];
  }
  return returnArray;
}
var data = objectifyForm($('form').serializeArray());
$.ajax({
  data: data,
  dataType: "text/json",
  type: "POST",
  url: "/api/savetransferee",
  success: success,
  error: error
});
devzero
  • 2,510
  • 4
  • 35
  • 55
  • When I inspect the 'Authorization` object in my action method I'm still seeing the `FamilyMembers` property as `null`. – Delfino Mar 20 '18 at 15:18
  • Updated answer so that you should get more correct code. – devzero Mar 20 '18 at 15:31
  • For my purposes, `FamilyMembers` is of type `ICollection` and not `FamilyMember[]` so instead of using `Model.FamilyMembers[i]` I have to use `Model.FamilyMembers.ElementAt(i)`, which still produces just `FirstName=Joseph&LastName=Jones&Age=10&Relationship=Son&FirstName=Mary&LastName=Jones&Age=16&Relationship=Daughter&FirstName=Mike&LastName=McDonald&Age=25&Relationship=Son`. – Delfino Mar 20 '18 at 15:46
  • I just changed the `ICollection` to `FamilyMember[]` and your answer worked~ – Delfino Mar 20 '18 at 17:17