2016-05-23 69 views
0

我有一个MVC c#web应用程序。将模型中的嵌套类对象返回到我的控制器

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

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

该模型允许复选框等在我使用Razor做的View中呈现。

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> 
} 

设置一个破发点,则用户提交查看/型号后,我得到这个:

enter image description here

正如您所看到的,选项值(仅在此阶段测试单选按钮)是空的。

我该怎么做,或者是否有“更干净”的方式来做到这一点?

感谢

+0

您是否选择了任何单选按钮? – SamGhatak

+0

@SamGhatak嗨,没有为这个测试,因为用户不可以,做任何更改 –

+0

好吧,这是一个有效的案例。但是我在问,即使在选择后你是否能够获得价值,还是仍然保持不变? – SamGhatak

回答

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属性,并且“选项”中有6个字符

+0

梦幻般的解释 - 谢谢:) –

相关问题