即使必需的输入为空,登录表单仍然发布

时间:2013-11-14 20:54:28

标签: asp.net-mvc-4 post client-side unobtrusive-validation

我在新的MVC4解决方案中使用jquery unobtrusive验证。我的问题是,在我的登录页面上,当我点击提交按钮时,即使我的必填字段为空,页面仍然会被发布。

我有另一个页面,我有相同的设置,而且没有发布。

这是我的登录页面:

<div id="loginForm">

    @Html.SiteLogo()
    @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <div id="loginForm-container" class="spacer-below">            
            <fieldset>
                <legend>Log in Form</legend>
                <div class="input-control text" data-role="input-control">                    
                    @Html.TextBoxFor(m => m.UserName, new { placeholder="Please enter your username"})
                    @Html.ValidationMessageFor(m => m.UserName)
                </div>                    

                <div class="input-control password" data-role="input-control">                                        
                    @Html.PasswordFor(m => m.Password, new { placeholder="Please enter your password"})
                    @Html.ValidationMessageFor(m => m.Password)
                </div>

                <div class="input-control checkbox" data-role="input-control">
                    <label>
                        @Html.CheckBoxFor(m => m.RememberMe)
                        <span class="check"></span>&nbsp;Remember me
                    </label>
                </div>

                <div class="input-control">    
                    <input type="submit" class="primary small" value="Log in" />
                </div>
            </fieldset>                
        </div>

        <div class="forgotPassword">@Html.ActionLink("Forgotten password?", "ForgotPassword")</div>
        <span>@Html.Partial("_CustomerSupport")</span>
    }
</div>

此页面的viewmodel:

public class LoginModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me")]
    public bool RememberMe { get; set; }
}

这是一个可以正常工作的页面的HTMl,即如果输入为空则不发布

<div id="resetPasswordForm">

    @Html.SiteLogo()
    <h4>Reset Password</h4>
    @using (Html.BeginForm(new {ReturnUrl = ViewBag.ReturnUrl}))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        @Html.HiddenFor(vm => vm.Authentication.Token)                
        @Html.ValidationMessageFor(vm => vm.Authentication.Token)

        <div id="resetPasswordForm-container" class="spacer-below">            
            <fieldset>
                <legend>Reset password form</legend>
                <div class="input-control text" data-role="input-control">                    
                    @Html.TextBoxFor(vm => vm.Authentication.EmailAddress, new { placeholder="Please enter your email address"})                        
                    @Html.ValidationMessageFor(vm => vm.Authentication.EmailAddress)
                </div>                    
                <div class="input-control password" data-role="input-control">                    
                    @Html.PasswordFor(vm => vm.NewPassword, new { placeholder="Please enter a new password"})                        
                    @Html.ValidationMessageFor(vm => vm.NewPassword)
                </div>                    
                <div class="input-control text" data-role="input-control">                    
                    @Html.PasswordFor(vm => vm.ConfirmPassword, new { placeholder="Please enter the password again"})                        
                    @Html.ValidationMessageFor(vm => vm.ConfirmPassword)
                </div>                                    
                <div class="input-control">    
                    <input type="submit" class="primary medium" value="Reset Password" />
                </div>
            </fieldset>                
        </div>
        <span>@Html.Partial("_CustomerSupport")</span>
    }
</div>

我的此页面的视图模型:

public class ResetPasswordViewModel
{
    public ResetPasswordViewModel()
    {
        Authentication = new ResetPasswordConfirmViewModel();
    }

    public ResetPasswordConfirmViewModel Authentication { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm new password")]
    [Compare("NewPassword", ErrorMessage = "The new passwords do not match, please enter again.")]
    public string ConfirmPassword { get; set; }
}

我的视图在查看源时引用了相应的脚本:

<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

我还应该提到我正在遵循以下指南:

http://nickstips.wordpress.com/2011/08/18/asp-net-mvc-displaying-client-and-server-side-validation-using-qtip-tooltips/

为了尝试像试验一样悬停。除登录表单外,这种方式完美无缺。经过进一步调查后,似乎代码在onError()方法更改时出错,因为可能没有对此字段进行验证(我不需要验证,因为它是可选的)。

var replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;

我猜测我的输入不是验证所必需的,它没有data-valmsg-replace属性,因此这行导致javascript失败,所以帖子通过了?

2 个答案:

答案 0 :(得分:2)

问题似乎是因为“记住我”复选框没有应用任何验证属性。当代码进入onError()方法时,它就失败了:

var replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;

as container.attr(“data-valmsg-replace”)是一个空字符串。

我用以下代码替换了这段代码:

var elementJson = container.attr("data-valmsg-replace") || 'false';
var replace = $.parseJSON(elementJson) !== false;

现在一切似乎都运转正常。我不确定这是否是编写javascript的最佳方式,但似乎可以解决问题。

问题中提到的原始代码来自:

MVC clientside and serverside using qTip

答案 1 :(得分:1)

确保您的视图引用脚本:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

这可能听起来很明显,但对于创建视图对话框中的某些选项,即使您已选中Reference script libraries,它也不会将脚本实际添加到视图中,因此值得仔细检查。 / p>

修改

刚刚注意到你正在使用MVC 4,在这种情况下,这可能是你在视图底部缺少的内容:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

如果没有捆绑脚本,我实际上能够重现验证没有触发的问题。