我有一个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我得到这个:
如您所见,Option值(仅在此阶段测试单选按钮)为空。
我应该做什么或者是否有一个清洁工&#39;这样做的方法?
由于
答案 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;