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

时间:2015-04-24 07:52:05

标签: javascript jquery ajax asp.net-mvc twitter-bootstrap

我有一个帐户控制器,我想在模态引导程序中输入错误的用户名/密码时它会返回一条消息“无效登录尝试”。从ActionResult登录()到模态。

我的_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>

我的控制器:

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

3 个答案:

答案 0 :(得分:0)

我添加了关于此的评论,但它可能有助于您的解决方案。听起来表单提交上的无效输入导致在空白页面上重定向模态内容?由于模态是局部视图,因此请尝试将脚本移动到_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>

答案 1 :(得分:0)

  • 首先,既然你正在使用@Ajax助手,你应该安装并引用Microsoft jQuery Unobtrusive Ajax(你可以在这里找到一个较旧但仍然相关的指南:https://www.asp.net/mvc/overview/older-versions/creating-a-mvc-3-application-with-razor-and-unobtrusive-javascript)。

  • 其次,您应启用客户端验证(请参阅指南)

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

答案 2 :(得分:0)

一般而言:

  1. 修改您的控制器以返回登录尝试的JSON结果
  2. 将提交按钮设为常规按钮,因此实际上不会提交。
  3. 使用JQuery构建JSON对象
  4. 使用JQuery将JSON对象发布到控制器
  5. 在您的AJAX中,检查从控制器返回并采取相应行动
  6. 为用户反馈添加一个小div
  7. 删除ModelState.AddModelError("", "Invalid login attempt.");
  8. 在你的控制器中,尝试/捕捉你的逻辑,这样它总是将JSON返回到模态的ajax。处理那里的错误(见下文)
  9. (显然,你可以使用任何选择,比如'成功'等等。)

    你的剃刀可能看起来像:

     // 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);