MVC AddModelError自定义错误未以Ajax形式显示

时间:2018-10-09 14:53:03

标签: asp.net-mvc asp.net-mvc-4 asp.net-mvc-3

我有一个登录表单,我想在其中显示与ValidationMessageFor消息相同的自定义错误,例如“用户不存在”。

我正在控制器中添加自定义错误,但未在表单中显示。

为了以Ajax格式显示验证消息,我使用了从控制器返回的登录PartialView的技术

感谢您的帮助!

控制器:

  [HttpPost]
        public ActionResult Login(Login login)
        {

            if (!ModelState.IsValid) //Check for validation errors
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return PartialView("_login", login);
            }

            ActiveDirectoryDAL.ADQueries ad = new ActiveDirectoryDAL.ADQueries();
            var userName = login.UserName.ToLower().Trim();
            var password = login.Password.Trim();


            var isValidUser = ad.Authenticate(userName, password);


            if (!isValidUser)
            {
                ModelState.AddModelError(string.Empty, "Login failed");
                return PartialView("_login", login);
            }

            FormsAuthentication.SetAuthCookie(login.UserName, false);
            return Json(new { RedirectUrl = Url.Action("Index", "Home") });

        }

视图

@model PushNotificationWebSite.Models.Login
@{
    ViewBag.Title = "Login";
    Layout = "";
}


<html>
<head>
    <link href="~/Content/login.css" rel="stylesheet" />
    @Styles.Render("~/Content/bootstrap/css")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
</head>
<script type="text/javascript">
    function OnSuccess(data) {
        if (data.RedirectUrl)
            window.location.href = data.RedirectUrl;
    }
    function OnLoginFailure(data) {
        debugger;
        $('#login').html(data.responseText);

    }
</script>

<body id="LoginForm">
    <div class="container">
        <h1 class="form-heading">login Form</h1>
        <div class="login-form">
            <div class="main-div">
                <div class="panel">
                    <h2>Admin Login</h2>
                    <p>Please enter your username and password</p>
                </div>
                @using (Ajax.BeginForm("Login", "Account", new AjaxOptions
                {
                    InsertionMode = InsertionMode.Replace,
                    HttpMethod = "POST",
                    LoadingElementId = "loader",
                    OnSuccess = "OnSuccess",
                    OnFailure = "OnLoginFailure"


                }, new { id = "login" }))
                {
                    @Html.ValidationSummary(true)
                    <div class="form-group">

                        @Html.TextBoxFor(model => model.UserName, new { @class = "form-control", autocomplete = "off", placeholder = "Username" })


                    </div>
                    <div class="form-group">

                        @Html.TextBoxFor(model => model.Password, new { @class = "form-control", autocomplete = "off", type = "password", placeholder = "Password" })
                        @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })

                    </div>

                    <button type="submit" class="btn btn-primary">Login</button>
                }
                <div id="loader" class="loader">
                    <img class="center" src="~/Images/ajax-loader.gif" />
                </div>
            </div>

        </div>
    </div>
</body>
</html>

部分视图:

@model PushNotificationWebSite.Models.Login

@using (Ajax.BeginForm("Login", "Account", new AjaxOptions
{
    HttpMethod = "POST",
    LoadingElementId = "loader",
    OnSuccess = "OnSuccess",
    OnFailure = "OnLoginFailure"


}, new { id = "login" }))
{
    @Html.ValidationSummary(true)
    <div class="form-group">

        @Html.TextBoxFor(model => model.UserName, new { @class = "form-control", autocomplete = "off", placeholder = "Username" })
        @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" })

    </div>
    <div class="form-group">

        @Html.TextBoxFor(model => model.Password, new { @class = "form-control", autocomplete = "off", type = "password", placeholder = "Password" })
        @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })

    </div>
    <button type="submit" class="btn btn-primary">Login</button>
}

2 个答案:

答案 0 :(得分:0)

您可以将任何字符串作为键名分配给自定义string.Empty错误,而不是使用ModelState作为键名。从此更改ModelState.AddModelError()

ModelState.AddModelError(string.Empty, "Login failed");

此示例:

ModelState.AddModelError("LoginFailed", "Login failed");

然后,将ValidationMessage助手放在部分视图内,其键名与在ModelState.AddModelError中分配的键名相同,如下例所示:

@* message without styling *@
@Html.ValidationMessage("LoginFailed")

@* message with styling *@
@Html.ValidationMessage("LoginFailed", new { @class = "text-danger" })

或使用ViewData.ModelState再次显示它,并使用相同的键名:

@ViewData.ModelState["LoginFailed"].Errors[0].ErrorMessage

注意:

除了InsertionMode.Replace设置之外,您还可以考虑在验证失败时使用UpdateTargetId更新部分视图的内容:

@using (Ajax.BeginForm("Login", "Account", new AjaxOptions
{
    InsertionMode = InsertionMode.Replace,
    HttpMethod = "POST",
    LoadingElementId = "loader",
    UpdateTargetId = "elementId", // here you can set HTML element ID to update
    OnSuccess = "OnSuccess",
    OnFailure = "OnLoginFailure"
}, new { id = "login" }))
{
    // form contents
}

答案 1 :(得分:0)

我找到了根本原因。

我忘记添加Response.StatusCode = (int)HttpStatusCode.BadRequest;

在发送return PartialView("_login", login);之前  服务器发送了响应OK 200,因此验证器没有触发