如何在服务器端的模态引导程序中进行验证?

Posted

技术标签:

【中文标题】如何在服务器端的模态引导程序中进行验证?【英文标题】:How can I validate in a modal bootstrap from server side? 【发布时间】:2015-07-02 17:13:36 【问题描述】:

我有一个Account 控制器,当在引导模式中输入了不正确的用户名/密码时,我希望它返回一条消息“登录尝试无效”。从ActionResult Login() 到模态。

我的_loginPartialView:

<div id="loginModal" class="modal fade">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title">Login</h4>
        </div>
        <div class="modal-body">
            <section id="loginForm">
                @using (Ajax.BeginForm("Login", "Account", new AjaxOptions  HttpMethod = "POST", UpdateTargetId = "loginModal" ))
                
                    @html.AntiForgeryToken()
                    @Html.ValidationSummary(true, "", new  @class = "text-danger" )
                    <div class="form-group">
                        @Html.LabelFor(m => m.Email, new  @class = "col-md-2 control-label" )
                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.Email, new  @class = "form-control" )
                            @Html.ValidationMessageFor(m => m.Email, "", new  @class = "text-danger" )
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(m => m.Password, new  @class = "col-md-2 control-label" )
                        <div class="col-md-10">
                            @Html.PasswordFor(m => m.Password, new  @class = "form-control" )
                            @Html.ValidationMessageFor(m => m.Password, "", new  @class = "text-danger" )
                        </div>
                    </div>
                    <div style="text-align:right;">
                        <button type="submit" class="btn btn-primary btn-sm">Submmit</button>
                    </div>
                

            </section>
        </div>
    </div>
</div>

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

<script>
    $(document).ready(function () 
        $('.launchLoginModal').click(function () 
            $('#loginModal').modal(
                keyboard: false
            );
        );
    );   
</script>

我的Account 控制器:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)

    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return PartialView("_LoginModalPartial", model);
    

【问题讨论】:

您是否考虑过使用 Ajax.BeginForm,然后将您的部分模态视图返回到页面中。 @Symeon 我尝试使用 Ajax.BeginForm 并在控制器中返回 PartialView,但是当我提交时它重定向到 localhost:xxxxx/Account/Login 并呈现部分视图。不显示模式对话框。我不想重定向到其他视图 听起来登录不成功,或者登录方法不允许匿名 - 尽管您在顶部确实有 [AllowAnonymous] 令牌。您是否在调试中尝试过它,看看它是否甚至进入了 Login 方法? @Symeon 是的,我已经调试过了,它进入了登录,之后它在“/Account/Login”视图中呈现了“_LoginModalPartial”。 所以它返回正确?如果是这样,如果您希望该错误仅在错误时返回,那么您还需要在您的 switch 语句中添加更多行 - 例如case SignInStatus.LockedOut: case SignInStatus.Success: etc 所以默认只有在登录尝试无效时才会发生 【参考方案1】:

我对此添加了评论,但它可能有助于您的解决方案。听起来表单提交中的无效输入会导致在空白页面上使用模态内容进行重定向?由于模态是局部视图,请尝试将脚本移动到 _loginPartialView 的顶部。这对于您在布局页面中使用的任何捆绑包都适用。

<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>
<div id="loginModal" class="modal fade">
       ...
</div>

【讨论】:

【参考方案2】:

首先,由于您使用的是 @Ajax 帮助程序,因此您应该安装并参考 Microsoft jQuery Unobtrusive Ajax(您可以在此处找到较旧但仍然相关的指南:https://www.asp.net/mvc/overview/older-versions/creating-a-mvc-3-application-with-razor-and-unobtrusive-javascript)。

其次,您应该启用客户端验证(参见指南)

第三,您需要将要更新的现有 DOM 元素指定为 UpdateTargetId(我在代码示例中没有看到“loginModal”)。我相信这个 id 应该在模态 html 代码中,否则它会重新创建模态 html 并重置其状态。 (我会在父视图中移动模态定义,让部分只包含表单定义)。

【讨论】:

【参考方案3】:

一般:

    修改控制器以返回登录尝试的 JSON 结果 将提交按钮设为常规按钮,这样它就不会真正提交。 使用 JQuery 构建 JSON 对象 使用 JQuery 将该 JSON 对象发布到您的控制器 在您的 AJAX 中,检查来自控制器的返回并采取相应措施 为用户反馈添加一个小 div 删除ModelState.AddModelError("", "Invalid login attempt."); 在您的控制器中,尝试/捕捉您的逻辑,以便它始终将 JSON 返回到模态的 ajax。在那里处理错误(见下文)

(显然,您可以使用任何诸如“成功”之类的词。)

你的剃须刀可能看起来像:

 // on login button click
    $('#btnSubmit').on('click', function()    
        $("#loginForm").validate(); // using jqueryvalidate
        if ($('#loginForm').valid())                       // if valid, submit
            // Get values from Modal and put into JSON object mimicking correct model
        var token = $('input[name="__RequestVerificationToken"]').val(); // this is required for the anti-forgery decoration and must be structured outside the model to be submitted
        var model = 
            Email: $('#Email').val(),
            Password: $('#Password').val()
            ;
        var ajaxData = 
            __RequestVerificationToken: token,
            model: model
        
             // send
        $.ajax(
            type: "GET",
            url: '@Url.Action("method", "controller")',
            data: ajaxData,
            success: function (msg) 
                 // ajax success, but see if the login was a success
                 if (msg.IsError == 'true' all good 
                 else  
                       if (msg.Message != 'success')
                            $('#UserFeedback').val('Invalid Login') 
                       
                      
            ,
            error: function(XMLHttpRequest, textStatus, errorThrown) 
                console.info(errorThrown);
                // userfeedback
                $('#UserFeedback').html(errorThrown);

                );
            
        );
        
    );

您的控制器可以返回一个自定义视图模型,例如:

public class LoginCheckViewModel
       
    [DisplayName("IsError")]
    public string IsError get; set;

    [DisplayName("Message")]
    public string Message  get; set;         

你的控制器会像你一样检查登录,然后返回

myLoginCheckViewModel = new LoginCheckViewModel();
myLoginCheckViewModel.IsError = [true/false];
myLoginCheckViewModel.Message = [success/fail];
return Json(myLoginCheckViewModel, JsonRequestBehavior.AllowGet);

【讨论】:

以上是关于如何在服务器端的模态引导程序中进行验证?的主要内容,如果未能解决你的问题,请参考以下文章

表单验证在引导程序中不起作用

如何使用引导程序将数据传递给模态

居中的模态负载微调器引导程序 4

无法更改 css 模态引导程序。引导程序中的模态淡入淡出自动添加填充左 15px

我应该如何在引导程序中包含链接以进行表单验证

html 在模态引导程序中显示外部链接