我的页面上有一个简单的单选按钮列表,我在视图中使用以下内容进行渲染:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender") %>
请注意,当用户最初看到此输入时,两个按钮都未被选中。 验证是强制他们选择而不是接受默认值。 因此,这两个单选按钮绑定到我的模型中的可为空的int属性,声明为:
public int? gender { get; set; }
因此,如果他们没有选择按钮并提交页面,则gender属性将为null,表示他们没有选择。在帖子期间,控制器会调用以下验证:
if (!gender.HasValue)
ModelState.AddModelError("gender", "gender required");
但是,如果验证失败(他们没有选择),那么在渲染阶段,MVC框架会抛出以下异常:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
在寻找这个问题的解决方案时,我注意到有几个人遇到了这个问题。 我正在使用ASP.NET MVC 1.0。我在代码中找到了使用.NET Reflector抛出此错误的位置。
问题是如何使这项工作正确?
编辑:添加stacktrace:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="System.Web.Mvc"
StackTrace:
at System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType)
at System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper, InputType inputType, String name, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, Boolean isChecked, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value)
at ASP.views_vbs_register_aspx.__RenderregisterContent(HtmlTextWriter __w, Control parameterContainer) in c:\Users\David\Documents\BellevueProject\Bellevue\BellevueTeachers\Forms\Views\VBS\Register.aspx:line 42
答案 0 :(得分:11)
我只是尝试了一些让这项工作成功的东西。 如果我不进行验证步骤,但当然我需要验证,则不会出现此问题。 这给了我一个解决方案的线索。
ValidationMessage HtmlHelper方法接受一个字符串参数,该参数是要验证的属性或模型对象的名称。 我刚刚将该名称更改为“gender2”,如下所示:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender2") %>
我更改了验证码以引用这个新名称(即使该属性不存在,它仍然有效):
if (!gender.HasValue)
ModelState.AddModelError("gender2", "gender required");
这可以按预期工作。
我本以为对方应该有用,但这是一个简单的解决方法,我在这里记录。
编辑: 顺便说一下,我尝试将gender属性更改为字符串而不是可以为null的int,并且会出现同样的问题。
解决方法似乎仍然是使用验证消息的不同密钥名称。
答案 1 :(得分:7)
这非常相似,如果不等于复选框问题:Html.Checkbox()辅助方法生成一个带有false值的隐藏字段。如果缺少此字段,浏览器将不会为未选中的框发送任何数据。
然而,无线电按钮应该具有值,并且可能的值可以多于一个。在这种情况下,处理非选择案例并不是那么容易,我猜是不是这样的原因。
我的解决方法是添加隐藏字段,如下所示:
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.Hidden("gender", null) %>
答案 2 :(得分:1)
您可能想尝试将性别更改为字符串(M / F)而不是int,并查看是否有效。
如果你绝对必须把它作为一个int,你总是可以在后端翻译。
private int? gender { get; set; }
public string displayGender
{
get
{
return this.gender.HasValue
? (this.gender.Value == 1 ? "M" : "F" )
: null;
}
set
{
this.gender = null;
if (value == "M")
this.gender = 1;
else if (value == "F")
this.gender = 2;
}
}
<label for="gender">Gender</label>
<%= Html.RadioButton("displayGender", "M") %> Male
<%= Html.RadioButton("displayGender", "F") %> Female
<%= Html.ValidationMessage("displayGender") %>
根据您的评论,您可能想要添加:
<%= Html.RadioButton("displayGender",
string.Empty,
true, // this is the default
new { @style = "display: none;" } ) %>
这将确保displayGender被回发(总会有一个选定的无线电),我认为该值将是string.Empty而不是null引用。如果这样做,您可能想尝试切换回可以为空的int。
答案 3 :(得分:1)
尝试在ModelState.AddModelError()
:
ModelState.SetModelValue("gender", ValueProvider["gender"]);
答案 4 :(得分:1)
如果您想连接客户端验证。跳过html助手并手写你的无线电,为data-val和data-val-required提供属性。像这样。
<input type="radio" name="displayGender" id="displayGender" value="1" data-val="true" data-val-required ="The gender field is required."/>
<input type="radio" name="displayGender" id="displayGender" value="2" data-val="true" data-val-required ="The gender field is required."/>