基于ASP.NET MVC Remote验证的AdditionalFields与checkbox搭配使用的BUG
2013-02-19 07:42
671 查看
本方测试环境:ASP.NET MVC 4.0, .NET FRAMEWORK 4.0, VS 2012, 当前环境自带jquery.validate.unobtrusive.js
演示BUG:
MODEL类:
public class LoginModel
{
[Required]
[Remote("ValidateCCID", "Login", AdditionalFields = "IsStudent")]
public string CCID { get; set; }
VIEW:
@using (Html.BeginForm("LoginSHTracker", "Login",FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
CampusConnect ID:
<label>
@Html.EditorFor(m => m.CampusConnectID)
@Html.ValidationMessageFor(m => m.CampusConnectID)
</label>
<br />
<br />
<input type="submit" value="Login"/>
@Html.EditorFor(m => m.IsStudent)这里默认不被选中,也就是说测试的最终目标结果应该是false
Student
}
CONTROLLER:
public class LoginController : Controller
{
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public JsonResult ValidateCCID(string CCID,bool IsStudent)
{
这里IsStudent的值实际上是true
...
}
[HttpPost]
public ActionResult LoginSHTracker(LoginModel model)
{
这里model.IsStudent值实际上是false
...
}
}
我们本应该想要的结果是都为false,但是REMOTE验证传递的IsStudent值却为true。
下面阐述一下原因及解决方案:
jquery.validate.unobtrusive中获取IsStudent的方法是这一行:$(options.form).find(":input[name='" + escapeAttributeValue(paramName) + "']").val()
为了简单测试,就是$("form").find(":input[name='IsStudent']").val()
@Html.EditorFor(m => m.IsStudent)生成的HTML代码如下:
<input class="check-box" data-val="true" data-val-required="The IsStudent field is required." id="IsStudent" name="IsStudent" type="checkbox" value="true" /><input name="IsStudent" type="hidden" value="false" />
问题就出在这段HTML代码中。这两个HTML元素,name都是IsStudent。第一个元素的类型是checkbox,值为true。第二个元素的类型是hidden,值为false。$("form").find(":input[name='IsStudent']").val()这句话会先找到name为IsStudent的两个input元素,val()取第一个的值。所以,$("form").find(":input[name='IsStudent']").val()的值就是true。
然而,checkbox选项并没有选中,因此name为IsStudent的元素POST提交表单后服务器端得到的只有hidden的值,即false。(简单提一下ASP.NET MVC中EditorFor生成此段HTML的原因。在使用checkbox时,没有被选中的checkbox在服务器端取到的是NULL也就是取不到。因此bool值checkbox没有选中时,后台取到的仅是name相同的hidden的值false。如果此checkbox被选中,后台则同时取到两个值,即“true,false”。ASP.NET
MVC绑定MODEL时会取第一个值true进行绑定。)
两个值的不同也就造就了使用REMOTE验证AdditionalFields的BUG。
解决方案有多种,很简单的一种是:
<input type="checkbox" name="IsStudent" onclick="if (this.checked == true) { this.value = 'true'; } else { this.value = 'false';}" value="false"/>
直接写HTML代替ASP.NET MVC的EditorFor,并设置value="false"。然后加上click方法onclick="if (this.checked == true) { this.value = 'true'; } else { this.value = 'false';}
当然,您也可以修改jquery.validate.unobtrusive.js来避免这个问题的产生。或许新的ASP.NET MVC版本中会改善jquery.validate.unobtrusive.js。
演示BUG:
MODEL类:
public class LoginModel
{
[Required]
[Remote("ValidateCCID", "Login", AdditionalFields = "IsStudent")]
public string CCID { get; set; }
public bool IsStudent { get; set; } }
VIEW:
@using (Html.BeginForm("LoginSHTracker", "Login",FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
CampusConnect ID:
<label>
@Html.EditorFor(m => m.CampusConnectID)
@Html.ValidationMessageFor(m => m.CampusConnectID)
</label>
<br />
<br />
<input type="submit" value="Login"/>
@Html.EditorFor(m => m.IsStudent)这里默认不被选中,也就是说测试的最终目标结果应该是false
Student
}
CONTROLLER:
public class LoginController : Controller
{
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public JsonResult ValidateCCID(string CCID,bool IsStudent)
{
这里IsStudent的值实际上是true
...
}
[HttpPost]
public ActionResult LoginSHTracker(LoginModel model)
{
这里model.IsStudent值实际上是false
...
}
}
我们本应该想要的结果是都为false,但是REMOTE验证传递的IsStudent值却为true。
下面阐述一下原因及解决方案:
jquery.validate.unobtrusive中获取IsStudent的方法是这一行:$(options.form).find(":input[name='" + escapeAttributeValue(paramName) + "']").val()
为了简单测试,就是$("form").find(":input[name='IsStudent']").val()
@Html.EditorFor(m => m.IsStudent)生成的HTML代码如下:
<input class="check-box" data-val="true" data-val-required="The IsStudent field is required." id="IsStudent" name="IsStudent" type="checkbox" value="true" /><input name="IsStudent" type="hidden" value="false" />
问题就出在这段HTML代码中。这两个HTML元素,name都是IsStudent。第一个元素的类型是checkbox,值为true。第二个元素的类型是hidden,值为false。$("form").find(":input[name='IsStudent']").val()这句话会先找到name为IsStudent的两个input元素,val()取第一个的值。所以,$("form").find(":input[name='IsStudent']").val()的值就是true。
然而,checkbox选项并没有选中,因此name为IsStudent的元素POST提交表单后服务器端得到的只有hidden的值,即false。(简单提一下ASP.NET MVC中EditorFor生成此段HTML的原因。在使用checkbox时,没有被选中的checkbox在服务器端取到的是NULL也就是取不到。因此bool值checkbox没有选中时,后台取到的仅是name相同的hidden的值false。如果此checkbox被选中,后台则同时取到两个值,即“true,false”。ASP.NET
MVC绑定MODEL时会取第一个值true进行绑定。)
两个值的不同也就造就了使用REMOTE验证AdditionalFields的BUG。
解决方案有多种,很简单的一种是:
<input type="checkbox" name="IsStudent" onclick="if (this.checked == true) { this.value = 'true'; } else { this.value = 'false';}" value="false"/>
直接写HTML代替ASP.NET MVC的EditorFor,并设置value="false"。然后加上click方法onclick="if (this.checked == true) { this.value = 'true'; } else { this.value = 'false';}
当然,您也可以修改jquery.validate.unobtrusive.js来避免这个问题的产生。或许新的ASP.NET MVC版本中会改善jquery.validate.unobtrusive.js。
相关文章推荐
- ASP.NET MVC 使用Remote特性实现远程属性验证
- ASP.NET MVC 使用Remote特性实现远程属性验证
- ASP.NET MVC 3.0(十): MVC 3.0 使用 Forms身份验证
- asp.net中使用基于角色的身份Forms验证 (3)
- asp.net中使用基于角色role的Forms验证
- ASP.NET MVC使用Filter实现页面验证与授权
- ASP.NET MVC 5改进了基于过滤器的身份验证
- ASP.NET MVC使用AuthenticationAttribute验证登录
- 通过扩展改善ASP.NET MVC的验证机制[使用篇]
- Asp.net Mvc自定义客户端验证(CheckBox列表的验证)
- 光脚丫学ASP.NET MVC(0004):在ASP.NET MVC中使用Forms身份验证
- ASP.NET MVC 随想录—— 使用ASP.NET Identity实现基于声明的授权,高级篇
- Asp.net MVC 通过Attribute验证datamodel(二) ---使用IClientValidatable
- ASP.NET MVC中CheckBoxList的验证
- 在ASP.NET MVC中使用Knockout实践05,基本验证
- ASP.NET MVC基于标注特性的Model验证:ValidationAttribute
- 如何使用 C# .NET 在 ASP.NET 应用程序中实现基于窗体的身份验证
- Asp.net MVC P2 中无法正确获取 CheckBox值的bug的解决方案
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
- 使用 C# .NET 在 ASP.NET 应用程序中实现基于窗体的身份验证