Fuli
Fuli

Reputation: 273

How to pass list from view to controller

I have problem when pass a list in an object from view to controller, the list is always null. How should I do this?

My model:

public class ImageModel
{
    public int id { get; set; }
    public string url { get; set; }
    public bool delete { get; set; }
}

public class SchoolImages
{
    public Nullable<int> schoolid { get; set; }
    public IList<ImageModel> images;
}

The view:

@model SchoolAppManager.Models.SchoolImages

@using (Html.BeginForm("DeleteImages", "Images"))
{

    @Html.HiddenFor(x => x.schoolid)
    <table>
    @for (int i = 0; i < Model.images.Count(); i += 4) {

        <tr>
            <td>
                <img src="@Url.Content(Model.images[i].url)" width="50%" />
                <br />
                @Html.CheckBoxFor(x => x.images[i].delete)
                @Html.HiddenFor(x => x.images[i].id)
            </td>
            <td>
                @if (i + 1 < Model.images.Count())
                {
                    <img src="@Url.Content(Model.images[i + 1].url)" width="50%" />
                    <br />
                    @Html.CheckBoxFor(x => x.images[i + 1].delete)
                    @Html.HiddenFor(x => x.images[i + 1].id)
                }
            </td>
            <td>
                @if (i + 2 < Model.images.Count())
                {
                    <img src="@Url.Content(Model.images[i + 2].url)" width="50%" />
                    <br />
                    @Html.CheckBoxFor(x => x.images[i + 2].delete)
                    @Html.HiddenFor(x => x.images[i + 2].id)
                }
            </td>
            <td>
                @if (i + 3 < Model.images.Count())
                {
                    <img src="@Url.Content(Model.images[i + 3].url)" width="50%" />
                    <br />
                    @Html.CheckBoxFor(x => x.images[i + 3].delete)
                    @Html.HiddenFor(x => x.images[i + 3].id)
                }
            </td>
        </tr>
    }
    </table>

    <input type="submit" value="delete" />
}

When I click delete, SchoolImages is passed to the controller, SchoolImages.schoolId has value in the controller, however, SchoolImages.images is null. How can I pass SchoolImages.images to controller?

Upvotes: 8

Views: 20683

Answers (4)

free4ride
free4ride

Reputation: 1643

It's null because the default model binder doesn't know how to initialize it. Change your field images to be a property and add a constructor like this:

public class SchoolImages
{
    public SchoolImages()
    {
        images = new List<ImageModel>();
    }
    public Nullable<int> schoolid { get; set; }
    public IList<ImageModel> images { get; set; }
}

It should work.

Upvotes: 0

Sayan Pal
Sayan Pal

Reputation: 4956

Try changing your model "SchoolImages"; use array instead of IList<>.

Upvotes: 0

Ashish Charan
Ashish Charan

Reputation: 2387

I guess you will have problem binding complex types to your model. In case you don't get that working. Here is the alternative way.

You have a bunch of checkboxes, possibly with the same name and different values. You could post them to a method that takes a FormCollection, ie.

public ActionResult Test(FormCollection collection)
{
    string results = collection["Blanks"];
}

This would give you a comma-delimited list of values (or null, where no checkboxes are ticked).

Alternatively, if you have the possible values as an array on the server then you could give the checkboxes names according to their array values, which would mean you could do something like this:

@using (Html.BeginForm("Test","Home"))
{
    @Html.CheckBox("Blanks[0]", false);
    @Html.CheckBox("Blanks[1]", false);
    @Html.CheckBox("Blanks[2]", false);

    <input type="submit" value="Submit" />
}

giving you an array of booleans in your Test method:

public ActionResult Test(bool[] Blanks) { }

Upvotes: 1

Zabavsky
Zabavsky

Reputation: 13640

Default model binder doesn't work with fields, so make images a property:

public IList<ImageModel> images { get; set; }

Upvotes: 7

Related Questions