0

Let's say I have an object like this:

public class Widget
{
    public string Name { get; set; }
    public IEnumerable<Foo> Foos { get; set; }
}

public class Foo
{
    public string Name { get; set; }
}

And my controller method sends it to a View like this:

var widget = _dataAccess.GetWidget(someKey);
return View(widget);

And I have a View that looks like this:

@model MyNamespace.Widget

@using(Html.BeginForm("Edit", "Widgets", FormMethod.Post, new { id = "the-form" }))
{
    <p>@Html.TextBoxFor</p>

    @foreach(var foo in Model.Foos)
    {
        <p>@Html.TextBoxFor(x => x.Foos.ToList()[Model.Foos.ToList().IndexOf(foo)])</p>   
    }

    <input type="button" value="Save Changes" id="the-button" />
}

<script type="text/javascript">
$(function () {
        $("#the-button").click(function () {
            $.ajax({
                url: '@Url.Action("Edit", "Widgets")',
                type: 'POST',
                data: JSON.stringify({ widget: serializeForm("the-form") }),

                // etc, etc, not important
            });
        });
    });
    function serializeForm(formId) {
        var formData = {};
        $.each($("#" + formId).serializeArray(), function(){
            formData[this.name] = $(this).val();
        });
        return formData;
    }
</script>

Which serializes into:

{ "widget": { "Name" : "value from textbox", "[0].Name" : "some value", "[1].Name" : "some other value" } }

Of Course the serialization here isn't helpful because [0].Name isn't usable. Is there a way to change this so that it serializes to what the Post method controller action would expect? I.e., something like:

{ "widget":{"Name":"blah", "Foos":[ { "Name":"foo name 1"}, { "Name":"foo name 2"} ] }}
1
  • Does it have to be json or just something that will bind to Widget? Commented Dec 4, 2012 at 22:25

1 Answer 1

1

You can output the Foos as:

for (int i = 0; i < Model.Foos.Count(); i++) {
    <input type="text" name="Foos[@i].Name" value="@Model.Foos.ElementAt(i).Name" />
}

You can then easily post the form:

 $("#the-button").click(function () {
    $.ajax({
        url: '@Url.Action("Edit", "Widgets")',
        type: 'POST',
        data: $('this').closest('form').serialize(),

        // etc, etc, not important
    });
});

Phil Haack's post on model binding a list explains this in depth.

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

2 Comments

I did figure this out eventually from a Phil haack post on this topic. Doesn't make your answer any less correct though, thank you kindly!
That's a great reference. I've added a link to it in the answer.

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.