Binding to an object with properties and a list

2019-09-03 07:23发布

问题:

I've been able to bind a list of objects correctly. Works fine. Now when I change the item a complex object it stops working.

The complex object is the room name with the list of objects. When the 'postback' the name returns fine, but the list of objects comes back as null.

Any hints please?

Room Model:

    public class Room
{
    public string Name { get; set; }
    public List<Option> Options { get; set; }

    public Room() { }
    public Room(string name, List<Option> options)
    {
        Name = name; Options = options;
    }
}

Options Model

public class Option
{
    public bool IsSelected { get; set; }
    public string ImagePath { get; set; }
    public int UniqueID { get; set; }

    public Option() { }
    public Option(bool isSelected, string imagePath, int uniqueID)
    { IsSelected = isSelected; ImagePath = imagePath; UniqueID = uniqueID; }
}

HomeController

    public ActionResult Index()
    {
        List<Option> options = new List<Option>();

        options.Add(new Option(true, "../Content/cars_2.jpg", 4));
        options.Add(new Option(true, "../Content/vw_one_liter_concept01_2.jpg", 6));
        options.Add(new Option(false, "../Content/00018578.jpg", 8));
        //Get a list of selected options and union with all remaining

        Room model = new Room("Room1", options);

        return View(model);
    }
    [HttpPost]
    public ActionResult Index(Room model)
    {
        ViewData["results"] = model.Options.Count();
        return View(model);
    }

Index View

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MultiSelect.Models.Room>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Index</title>
    <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery-ui-1.8.10.custom.min.js" type="text/javascript"></script>


</head>
<body>

<% using (Html.BeginForm())
   {%>
    <%= Html.ValidationSummary(true)%>
    <%= Html.TextBoxFor(m=> m.Name) %>
    <% Html.RenderPartial("MultiSelect", Model.Options); %>

<% } %>
</body>
</html>

MultiSelect Partial View

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<MultiSelect.Models.Option>>" %>
<% for (int counter = 0;counter< Model.Count(); counter ++)
   { %>
    <div class="opt">
        <%= Html.HiddenFor(i=> i[counter].UniqueID)%>
        <%= Html.HiddenFor(i=> i[counter].ImagePath) %>
        <%= Html.CheckBoxFor(i => i[counter].IsSelected)%>
        <img src="<%= Model.ElementAt(counter).ImagePath %>" alt="Image" width="128" height="128" />
    </div>
<% } %>
<input id="Submit1" type="submit" value="submit" />

回答1:

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ provides a solution for what you're looking for.

Alternatively, an easier, but less flexible solution is to put a Room.cshtml file, and a Option.cshtml file in your Shared/EditorTemplates folder. Then you'd put

<%= Html.TextBoxFor(m=> m.Name) %>
<% Html.EditorFor(m => m.Options); %>

in Room.cshtml

<% Html.EditorFor(m => Model); %>

in index, and the contents of your partial view in Option.cshtml.