0

从过去的 3 天开始,我一直在这方面苦苦挣扎。我有一个 _Layout 页面,其中我在单击登录按钮时在模态 div 中加载登录部分视图。当我提交时,如果有任何客户端验证都可以正常工作,并且在提供适当的数据之前不会提交表单。发生服务器端验证时会出现问题。如果凭据无效,它将重定向到同一页面,但不会显示模式。当我再次单击登录按钮时,无效凭据错误消息将以模式显示。我想知道这是否可以通过我尝试的方式实现,或者是否有任何其他方式可以实现这一目标。

这是_Layout Page 的一部分:

<a class="btn btn-style btn-success btn-lg btn-wid" data-target="#modal" data-toggle="modal" id="flogin"> Login </a>

以及页脚下方同一页面中的模态 div :

<div id="modal" class="modal">
    @{Html.RenderPartial("_Login", new Sample.Models.LoginModel());}
</div>

这是_Login 部分视图:

@model Sample.Models.LoginModel
@section Validation {
    @Scripts.Render("~/bundles/jqueryval")
}

<section id="Login">

    @using (Html.BeginForm("Login", "Home", FormMethod.Post, new { enctype = "multipart/form-data", id = "LoginForm", ReturnUrl = ViewBag.ReturnUrl }))
    { 
        <div class="modal-content wrap col-md-4 col-xs-12 col-sm-12 col-md-offset-4">

            @Html.AntiForgeryToken()
            <div class="row">
                <button type="button" class="close" id="btnLoginModalClose" style="margin-top:-15px" data-dismiss="modal" aria-hidden="true">×</button>
            </div>

            <div class="row-fluid">
                <div id="LoginDialog" class="col-md-12">
                    <div class="modal-header">
                        <h3 id="login" class="modal-title">
                            Freshers Login
                        </h3>
                        <div class="ui-state-error-text">
                            @if (TempData["ModelState"] != null)
                            {
                                @TempData["ModelState"]
                            }

                        </div>
                    </div>

                    <div class="modal-body">
                        <div class="form-group">
                            <span class="ico-email"></span>
                            @Html.TextBoxFor(m => m.UserName, new { id = "floginEmail", placeholder = "Email", type = "email", @class = "input-lg ipt ip-email" })
                            <div class="text-danger">
                                @Html.ValidationMessageFor(model => model.UserName)
                            </div>
                        </div>
                        <div class="form-group">
                            <span class="ico-pwd"></span>
                            @Html.TextBoxFor(m => m.Password, new { id = "floginPassword", placeholder = "Password", type = "password", @class = "input-lg ipt ip-pwd" })

                            <a href="#" id="loginpswdshow" onclick="showhide($(this));"><span style="position:relative" id="sploginpswdshow" class="glyphicon glyphicon-eye-open show"></span></a>
                            <div class="text-danger">
                                @Html.ValidationMessageFor(model => model.Password)
                             </div>
                            </div>
                        <div class="form-group">

                            <div class="input-group">
                                <span class="input-group-addon">
                                    @Html.CheckBoxFor(m => m.RememberMe, new { id = "chkRemember", type = "checkbox", @class = "checkbox" })
                                </span>
                                @Html.LabelFor(m => m.RememberMe, new { @class = "form-control" })
                            </div><!-- /input-group -->
                        </div>
                    </div>
                    <div class="modal-footer" style="margin-top:14px">
                        <input type="submit" id="btnLogin" name="login" style="margin-top:-5px" class="btn btn-primary pull-left btn-flogin" value="Log-in" />
                        <div class="row-fluid">
                            <a class="text-center" style="font-size:medium" onclick="fresherForgotClick();" id="lnkForgot" href="#">Forgot password?</a>
                        </div>
                    </div>
                    <span class="text-info"><strong>Do not have an Account? <a class="btn alert-danger" id="btnCreateAccount">Click here to Create one!</a></strong></span>

                </div>
            </div>
        </div>
    }


</section>

这是我的HomeController,它有 _Login Post Action 结果

public ActionResult Login(string redirect, Models.FreshersModel model)
        {
            if (model.IsValid(model.UserName,model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                if (!String.IsNullOrEmpty(redirect) || String.Compare(redirect, "none", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (redirect != null) Response.Redirect(redirect, true);
                }
                else
                {
                    return View("Index", "User");
                }
            }
            ModelState.AddModelError("", "Incorrect User Credentials");
            //ModelState.AddModelError("", "You entered an invalid password");
            TempData["ModelState"] = "Incorrect User Credentials";
            //return null;
            return RedirectToAction("Index", "Home");
        }

请让我知道是否有可能通过以下方式实现这一目标。

4

1 回答 1

1

您的工作流程可能应遵循以下原则:

  1. 不要正常发布表单,而是使用 jQuery 或类似的方式异步发布表单。
  2. 返回带有真/假成功值和可选消息的 JsonResult。
  3. 如果成功值为真,则刷新页面,否则,将错误消息插入模态框。

首先,将您的登录操作修改为类似于以下内容:

public ActionResult Login(Models.FreshersModel model, string returnUrl)
{
    bool success = false;
    string message = "User name or password is incorrect.";

    if (ModelState.IsValid)
    {
        success = model.IsValid(model.UserName,model.Password);
        if(success)
        {
            message = string.Empty;
            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
        }
    }

    return Json(new { success = success, message = message });
}

其次,我已经将您的大部分模态恢复到(几乎)使模态插件工作所需的最低限度:

<div id="LoginDialog" class="modal hide">
    <div class="modal-header">
        <h3 id="login" class="modal-title">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            Freshers Login
        </h3>
    </div>
    <div class="modal-body">
        @using (Html.BeginForm("Login", "Home", new { returnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { id = "LoginForm", role="form" }))
        { 
            @Html.AntiForgeryToken()

            <div id="errors" class="ui-state-error-text">
            </div>

            <div class="form-group">
                <span class="ico-email"></span>
                @Html.TextBoxFor(m => m.UserName, new { id = "floginEmail", placeholder = "Email", type = "email", @class = "input-lg ipt ip-email" })
                <div class="text-danger">
                    @Html.ValidationMessageFor(model => model.UserName)
                </div>
            </div>
            <div class="form-group">
                <span class="ico-pwd"></span>
                @Html.PasswordFor(m => m.Password, new { id = "floginPassword", placeholder = "Password", @class = "input-lg ipt ip-pwd" })
                <div class="text-danger">
                    @Html.ValidationMessageFor(model => model.Password)
                 </div>
                </div>
            <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon">
                        @Html.CheckBoxFor(m => m.RememberMe, new { id = "chkRemember", @class = "checkbox" })
                    </span>
                    @Html.LabelFor(m => m.RememberMe, new { @class = "form-control" })
                </div><!-- /input-group -->
            </div>
        }
    </div>
    <div class="modal-footer">
        <a href="#" class="btn">Close</a>
        <button type="button" class="btn btn-primary" id="btnLogin">Login</button>
    </div>
</div>

第三,也是最后,在布局中添加一些 jQuery。如果需要,可以将其包装在 Razor 条件中,以便仅在用户未通过身份验证时才将其注入视图。

$(function(){

    $(document)
        .on('submit', '#LoginForm', function(e) {   
            e.preventDefault(); /* we're taking over the default behaviour */

            var url = $(this).attr('action');
            var formData = $(this).serialize();

            $.post(url, formData)
                .fail(function(jqxhr, status, error){
                    $('#errors').html('An error occurred. Please try again.');
                })
                .done(function(response, status, jqxhr){
                    if(response.success) {
                        window.location.redirect('/');
                    }
                    else {
                        $('#errors').html(response.message);
                    }
                });
        })
        .on('click', '#btnSubmit', function(e) {
            e.preventDefault();
            $('#LoginForm').trigger('submit');
        });

});

我遗漏了一些部分,比如关闭模式,但这应该让你开始。

于 2014-09-07T20:45:46.170 回答