我一直在扯我的头发试图弄清楚为什么ValidationController的动作没有被触发。
我在项目范围的web.config中启用了设置:
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
我有以下控制器:
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public class ValidationController : Controller
{
private readonly IUserRepository userRepository;
public ValidationController(IUserRepository userRepository)
{
this.userRepository = userRepository;
}
public JsonResult IsUserNameAvailable(string username)
{
User user = userRepository.Get(u => u.UserName == username);
if (user == null) return Json(true, JsonRequestBehavior.AllowGet);
else return Json(false, JsonRequestBehavior.AllowGet);
}
}
和以下视图模型:
[Required(ErrorMessage = "Required *")]
[StringLength(50, MinimumLength = 4, ErrorMessage = "Please keep the username between four and twenty character.")]
[Remote("IsUserNameAvailable", "Validation", ErrorMessage = "A user with this username already exists.")]
[Display(Name = "Username")]
public string UserName { get; set; }
我的表单中有以下字段:
<form id="registerForm">
...
@Html.ValidationMessageFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
@Html.LabelFor(m => m.UserName)
</form>
我做ajax表单提交,已经有服务器端验证工作完美:
$.post("/Account/Register", $('#registerForm').serialize(), function(){
updateFormWithServerGeneratedErrors();
})
尽管服务器为我的字段生成了正确的输入标记:
<input ... data-val-remote-url="/Validation/IsUserNameAvailable" data-val-remote-additionalfields="*.UserName" data-val-remote="A user with this username already exists." ... >
我可以通过输入url: "/Validation/IsUserNameAvailable? "用户名=SomeName",但提琴手没有显示任何请求被制作到这个url上的按键或焦点变化。
根据本教程,我不需要编写任何javascript来获得此工作。是的,当我开始修改表单时,我已经加载了jquery.validate.js和jquery.validate.unobtrusive.js脚本。
这里有什么问题?
我找到答案了。
引用Darin Dimitrov的话:
"对于动态添加到DOM中的元素,不显眼的验证不能开箱即用——例如,向服务器发送一个AJAX请求,返回一个部分视图,然后将这个部分视图注入到DOM中。
为了使其工作,您需要将这些新添加的元素注册到不显眼的验证框架中。为此,您需要调用$.validator.unobtrusive。解析新添加的元素。应该将此代码放入AJAX成功处理程序中,该处理程序将部分注入DOM。"
框架调用这个方法一次页面加载,在我的情况下的问题是,表单本身是一个jquery对话框,所以即使初始加载是"动态的"。我必须在dialog load:
上用不显眼的框架注册表单元素。$.validator.unobtrusive.parse('#registerForm');
我的ajax调用也会返回并替换表单,如果它没有在服务器端验证:
registerDialog.empty().html(result.viewResult);
所以我必须调用parse()的成功回调,以及确保验证继续工作后,ajax提交
您需要从
更改JsonResult方法参数名称public JsonResult IsUserNameAvailable(string username)
public JsonResult IsUserNameAvailable(string UserName)
应该与属性名相同,区分大小写
验证函数没有被触发的问题是,以下代码
public JsonResult IsUserNameAvailable(string username)
{
User user = userRepository.Get(u => u.UserName == username);
if (user == null) return Json(true, JsonRequestBehavior.AllowGet);
else return Json(false, JsonRequestBehavior.AllowGet);
}
应该添加到AccountController
,而不是ValidationController
。移除ValidationController
类并将IsUserNameAvailable
方法添加到AccountController
类中。
也改变模型中的行,它应该是这样的
[System.Web.Mvc.Remote("IsUserNameAvailable", "Account")]
这样问题就解决了
我也有同样的问题。修改如下:
public JsonResult IsUserNameAvailable(string username)
{
User user = userRepository.Get(u => u.UserName == username);
if (user == null) return Json(true, JsonRequestBehavior.AllowGet);
else return Json(false, JsonRequestBehavior.AllowGet);
}
:
public JsonResult IsUserNameAvailable(string Username)
{
User user = userRepository.Get(u => u.UserName == Username);
if (user == null)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json(false, JsonRequestBehavior.AllowGet);
}
username
到UserName
是你的
public string UserName { get; set; }
我想它是区分大小写的。
希望对你有帮助
您似乎忘记为表单指定绑定Action了。我尝试了下面的代码,它工作
<form id="registerForm" action="Controller/Action">
@Html.ValidationMessageFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
@Html.LabelFor(m => m.UserName)
</form>
或简单的:
@using(Html.BeginForm()) {
@Html.ValidationMessageFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
@Html.LabelFor(m => m.UserName)
}