我的视图中有不同类型的元素 - 文本框,选择,复选框和单选按钮。当我使用模型呈现这个强类型视图时,有一些元素会填充相应的模型值,但有某些类型和不存在的类型。单选按钮,复选框为空白。当涉及选择元素时,如果它们是使用@Html.DropDownListFor
辅助方法创建的,那么它们将获得正确的值,但如果它们只是简单的Html选择,其名称对应于模型属性,则选择默认的第一项。我用@Html辅助方法创建了复选框和单选按钮:
@Html.RadioButtonFor(x => x.PreferredReplyMethod, PreferredReplyMethod.Written.GetHashCode(), new { id = "rbReplyWritten" })
<label for="rbReplyWritten">Written</label>
@Html.RadioButtonFor(x => x.PreferredReplyMethod, PreferredReplyMethod.Verbal.GetHashCode(), new { id = "rbReplyVerbal" })
<label for="rbReplyVerbal">Verbal</label>
@Html.CheckBoxFor(x => x.IsUnderControl, new { id = "chkUnderControl" })
@Html.LabelFor(x => x.IsUnderControl, new { @for = "chkUnderControl" })
问题是,如果我将这些值发布回服务器,则所有保存的值都是正确的。我该怎么办?
答案 0 :(得分:2)
我终于找到了问题的原因。因此,当你阅读时,抓住你的咖啡(当然是那些像我一样不熟悉ASP.NET MVC模型的人)。正如我所说,我的复选框,单选按钮和选择元素(不是在DropDownListFor&lt;&gt;帮助方法的帮助下生成)没有正确的值。在回发表单时,我能够保存所有数据(复选框除外),我已正确输入数据库。但是当回读时,表单没有填充正确的值 - 选择了他们的第一个选项,单选按钮和复选框清除。问题的常见原因是value属性没有正确的值。所以我会一个接一个地触摸它们。
<select class="select-normal" name="ApplicationType"> <option value="0">--Choose--</option> <option value="1">Complaint</option> <option value="2">Proposal</option> <option value="3">Query</option> </select>
ApplicationType是自定义枚举类型。
public Enum ApplicationType{
Complaint=1
Proposal=2,
Query=3
}
当处于编辑/插入模式时,所选选项很容易绑定到相应的属性,因为存在从数值到枚举的隐式转换。但是在读取时,模型属性值是枚举成员的名称,而不是其基础值。因此,如果ApplicationType是ApplicationType.Proposal MVC引擎将查找具有相同名称的元素并将找到我们的select。然后它将尝试找到具有&#34; Proposal&#34;而不是2的值的选项,并且它不会找到任何。所以我们必须将值设置为枚举选项的名称,如下所示:
<select class="select-normal" name="ApplicationType"> <option value="0">--Choose--</option> <option value="Complaint">Complaint</option> <option value="Proposal">Proposal</option> <option value="Query">Query</option> </select>
但即便是这样也不足以选择正确的选项。问题是,对于要选择的选项,需要设置selected
属性,因此selected="selected"
。不幸的是我无法弄清楚如何实现这一目标,所以我在网上搜索并发现MVC 5.1中有一个新的Html扩展方法,即EnumDropDownListFor&lt;&gt;,你可以从{添加到你的项目中{3}}。此方法从枚举中生成html选择元素。在使用它之前,你必须记住两件事:
a)如果希望select显示用户友好名称,则需要使用Disaplay(Name =&#34; Enum1 display text&#34;)来装饰你的枚举选项 b)默认情况下,该方法将option元素的值设置为枚举的基础值。只需改变这个
string value = Convert.ChangeType(field.GetValue(null), baseEnumType).ToString();
到这个
string value=field.Name;
将此代码添加到项目后,您唯一需要做的就是添加这一行代码
@Html.EnumDropDownListFor(x => x.ApplicationType, new { @class = "select-normal" })
但是,当然,如果你设法控制选择性&#34;不知怎的,你可以选择旧的方式。这就是全部,你很高兴。
对于radiobuttons,我的错误是将值设置为Enum.GetHashCode()。所以改变这个
@ Html.RadioButtonFor(x =&gt; x.PreferredReplyMethod,PreferredReplyMethod.Verbal.GetHashCode())
这将解决问题
@ Html.RadioButtonFor(x =&gt; x.PreferredReplyMethod, PreferredReplyMethod.Verbal
.GetHashCode())
虽然有复选框,情况有点不同。如果我像这样明确地将Model传递给Html.BeginForm方法
@using(Html.Beginform(&#34; SaveDocument&#34;&#34; DocumentController&#34;,模型))
并调试动作方法我可以看到对应于复选框的模型属性(它们都是类型int
的所有类型)具有&#34; 0&#34;的值。因此,当他们回读这会导致复选框被取消选中。我还没有弄明白为什么,因为如果我让MVC引擎隐含地通过模型,这个问题就会消失。
@using(Html.Beginform("SaveDocument","DocumentController"))