5

我一直在努力弄清楚为什么没有触发 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?username=SomeName”但 Fiddler 没有显示在按键或焦点更改时对该 url 发出的任何请求。

根据本教程,我不需要编写任何 javascript 即可使其正常工作。是的,当我开始修改表单时,我已经加载了 jquery.validate.js 和 jquery.validate.unobtrusive.js 脚本。

这里有什么问题?

4

5 回答 5

5

好的,我找到了答案。

在这里引用 Darin Dimitrov的话:

“不显眼的验证在动态添加到 DOM 的元素时无法开箱即用 - 例如向服务器发送 AJAX 请求,该请求返回部分视图,然后将该部分视图注入到 DOM 中。

为了使其工作,您需要使用不显眼的验证框架注册这些新添加的元素。为此,您需要在新添加的元素上调用 $.validator.unobtrusive.parse。您应该将此代码放在将部分注入您的 DOM 的 AJAX 成功处理程序中。”

框架在页面加载时调用此方法一次,在我的场景中的问题是表单本身是一个 jquery 对话框,因此即使初始加载也是“动态的”。我必须在对话框加载时使用不显眼的框架注册表单元素:

$.validator.unobtrusive.parse('#registerForm');  

如果它没有在服务器端验证,我的 ajax 调用也将返回并替换表单,如下所示:

registerDialog.empty().html(result.viewResult);

所以我必须在成功回调上调用 parse() 以确保在 ajax 提交后验证继续工作。

于 2013-01-06T18:05:18.620 回答
2

您需要将您的 JsonResult 方法参数名称从

public JsonResult IsUserNameAvailable(string username)

public JsonResult IsUserNameAvailable(string UserName)

它应该与属性名称相同,区分大小写。

于 2016-06-01T13:52:20.840 回答
1

验证功能没有被触发的问题是这段代码

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")]

这将解决问题。

于 2012-12-30T03:56:02.257 回答
0

您似乎忘记为表单指定绑定操作。我在下面的代码中尝试了这个并且它有效

<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)
}
于 2013-01-03T03:29:33.030 回答
0

我有同样的问题。简单地改变这个:

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

我认为它区分大小写。

希望它会有所帮助:)

于 2014-03-19T15:41:15.730 回答