将模型中的嵌套类对象返回给我的控制器

时间:2016-05-23 10:56:23

标签: c# asp.net-mvc razor

我有一个MVC c#web app。

我有一个模型,它在我的控制器中填充并呈现给我的视图。

此模型具有第二级嵌套类List对象。

此模型允许在我使用Razor执行的视图中呈现复选框等。

Ultimatley,我希望用户能够选中/取消选中复选框值等。

但是现在,concpet的证明我只是想在我的控制器上调用一个方法来返回默认值。

我看到持久化模型数据的方法之一是使用隐藏字段。

这对第一级嵌套类对象起作用,但不适用于下一层。

为了更好地解释这些是我在此视图中使用的模型:

[Serializable]
[XmlRoot("preferences")]
public class PreferencesModel
{
    /// <summary>
    /// Message to display to user on UI
    /// </summary>
    [XmlIgnore]
    public string MessageToUser { get; set; }
    /// <summary>
    /// Stores Preferences
    /// </summary>
    [XmlElement("section")]
    public IList<SectionModel> SectionModel { get; set; }
}

[Serializable]
[XmlRoot("section")]
public class SectionModel
{
    /// <summary>
    /// Name of Section (for Grouping Purposes)
    /// </summary>
    [XmlAttribute("name")]
    public string Name { get; set; }
    /// <summary>
    /// List of Preferences for this section
    /// </summary>
      [XmlElement("preference")]
    public List<PreferenceModel> PreferenceModel { get; set; }
}

[Serializable]
[XmlRoot("preference")]
public class PreferenceModel
{
    /// <summary>
    /// Type of HTML Control ie radio button, textbox
    /// </summary>
    [XmlAttribute("type")]
    public string Type { get; set; }
    /// <summary>
    /// Name of Preference
    /// </summary>
    [XmlAttribute("name")]
    public string Name { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [XmlAttribute("value")]
    public string Value { get; set; }
     /// <summary>
     /// 
     /// </summary>
    [XmlElement("options")]
    public List<Option> Options { get; set; }
}

[Serializable]
[XmlRoot("options")]
public class Option
{
    /// <summary>
    /// 
    /// </summary>
    [XmlAttribute("OptionName")]
    public string OptionName { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [XmlAttribute("OptionValue")]
    public string OptionValue { get; set; }
}

这是我关于模型位的视图:

@for (int i = 0; i != Model.SectionModel.Count; i++)
{
    @Html.HiddenFor(m => m.SectionModel[i].Name, "Name")
    <div style="clear: left; padding-left: 20px;">
        <h1>@Html.Label(Model.SectionModel[i].Name)</h1>
        <div class="clear"></div>
        @for (int j = 0; j != Model.SectionModel[i].PreferenceModel.Count; j++)
        {
            @Html.HiddenFor(m => m.SectionModel[i].PreferenceModel[j].Type, "type")
            @Html.HiddenFor(m => m.SectionModel[i].PreferenceModel[j].Name, "Name")


            switch (Model.SectionModel[i].PreferenceModel[j].Type)
            {
                case "check":
                    <p>@Html.Label(Model.SectionModel[i].PreferenceModel[j].Name)</p>
                    for (var r = 0; r != Model.SectionModel[i].PreferenceModel[j].Options.Count(); r++)
                    {
                        if (Model.SectionModel[i].PreferenceModel[j].Value == Model.SectionModel[i].PreferenceModel[j].Options[r].OptionValue)
                        {
                            @Html.CheckBox(Model.SectionModel[i].PreferenceModel[j].Options[r].OptionName,true)
                        }
                        else
                        {
                             @Html.CheckBox(Model.SectionModel[i].PreferenceModel[j].Options[r].OptionName, false)
                        }
                        @Html.LabelFor(x => x.SectionModel[i].PreferenceModel[j].Value, Model.SectionModel[i].PreferenceModel[j].Options[r].OptionName)
                    }
                    break;
                case "radio":
                    <b>@Html.Label(Model.SectionModel[i].PreferenceModel[j].Name)</b>
                        for (var r = 0; r != Model.SectionModel[i].PreferenceModel[j].Options.Count(); r++)
                        {
                            @Html.HiddenFor(m => m.SectionModel[i].PreferenceModel[j].Options, "option")
                            @Html.HiddenFor(m => m.SectionModel[i].PreferenceModel[j].Options[r].OptionValue,"OptionValue")
                            @Html.HiddenFor(m => m.SectionModel[i].PreferenceModel[j].Options[r].OptionName, "OptionName")

                            if (Model.SectionModel[i].PreferenceModel[j].Value == Model.SectionModel[i].PreferenceModel[j].Options[r].OptionValue)
                            {
                                @Html.RadioButtonFor(m => m.SectionModel[i].PreferenceModel[j].Value, Model.SectionModel[i].PreferenceModel[j].Options[r].OptionValue, new
                                {
                                    @checked = true
                                })
                            }
                            else
                            {
                                @Html.RadioButtonFor(m => m.SectionModel[i].PreferenceModel[j].Value, Model.SectionModel[i].PreferenceModel[j].Options[r].OptionValue)
                            }
                            @Html.LabelFor(x => x.SectionModel[i].PreferenceModel[j].Value, Model.SectionModel[i].PreferenceModel[j].Options[r].OptionName)
                        }
                    break;
                case "text":
                    <b>@Html.Label(Model.SectionModel[i].PreferenceModel[j].Name)</b>
                    @Html.TextBoxFor(m => m.SectionModel[i].PreferenceModel[j].Value)
                    break;
                case "textarea":
                   <b> @Html.Label(Model.SectionModel[i].PreferenceModel[j].Name)</b>
                    @Html.TextAreaFor(m => m.SectionModel[i].PreferenceModel[j].Value)
                    break;
                case "combo":
                   <b>@Html.Label(Model.SectionModel[i].PreferenceModel[j].Name)</b>
                    var options = Model.SectionModel[i].PreferenceModel[j].Options;
                    var items = new SelectList(options, "OptionValue", "OptionName");
                    @Html.DropDownList("Options",items,Model.SectionModel[i].PreferenceModel[j].Value)
                    @Html.Hidden("Options",Model.SectionModel[i].PreferenceModel[j].Options)
                   break;
                default:
                    <div>test dud</div>        
                    break;
            }
             <div class="clear"></div>
        }
    </div>
}

设置一个断点然后用户提交View / Model我得到这个:

enter image description here

如您所见,Option值(仅在此阶段测试单选按钮)为空。

我应该做什么或者是否有一个清洁工&#39;这样做的方法?

由于

1 个答案:

答案 0 :(得分:2)

您需要从视图中删除以下内容

@Html.HiddenFor(m => m.SectionModel[i].PreferenceModel[j].Options, "option")

Options是一个复杂属性(typeof List<Option>)和你生成的html

<input type="hidden" value="System.Collections.Generic.List[yourAssembly.Option]" length="6" ... />

value属性是因为它是属性的.ToString()值,并且它无法绑定到您的集合,因此绑定失败。请注意length="6"是因为HiddenFor()的第二个参数添加了html属性,而#34;选项中有6个字符&#34;