【问题标题】:Display mvc partial view with errors on parent page在父页面上显示带有错误的 mvc 部分视图
【发布时间】:2015-09-29 18:12:07
【问题描述】:

我有一个包含多个表单的页面,每个表单都是一个部分。我想在提交时发布每个部分。如果有错误,我希望验证错误作为主页的一部分显示在部分中,即如果有错误,我不想只在它自己的页面上看到部分。我是否正确地说这种行为只有在 ajax 帖子中才有可能?我如何在没有 ajax 帖子的情况下返回模型状态错误,而只是一个普通的表单帖子?

编辑: 仍然在它自己的页面上看到部分

部分 -

@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" }))
{
    @Html.ValidationMessage("InvalidUserNamePassword")
    <fieldset class="fieldset">
        <div>
            <label for="form-field-user_id">User ID</label>
            <span>
                @Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text", @id = "form-field-user_id"})                      
            </span>
        </div>
    </fieldset>
    <div class="form-field__button">
        <button id="loginButton" type="submit" class="button button--primary">Login</button>
    </div>
}

<script>
    $('#loginButton').click(function () {
        $.ajax({
            type: "POST",
            url: '@Url.Action("Login", "Account")',
            data: $('form').serialize(),
            success: function (result) {
                if (result.redirectTo) {
                    window.location.href = result.redirectTo;
                } else {
                    $("#LoginForm").html(result);
                }
            },
            error: function () {
                $("#LoginForm").html(result);
            }
        });
    });
</script>

控制器 -

[HttpPost]
public ActionResult Login(LoginModel model)
{
    if (!ModelState.IsValid)
    {
        return PartialView("~/Views/Account/_Login.cshtml", model);
    }
    return Json(new { redirectTo = Url.Action("Index", "Profile") });
}

【问题讨论】:

  • 您希望主页上的模型状态错误除了局部错误吗?
  • 你只需返回表单的部分视图,并在ajax成功回调中将原始表单替换为返回的html
  • 我希望部分模型状态错误,但部分必须像提交表单之前一样显示在主页上,而不是单独显示
  • @StephenMuecke 你能给我一个例子/链接吗?

标签: error-handling asp.net-mvc-5 partial-views


【解决方案1】:

是的,你说得对 这种行为只有在 ajax 帖子中才有可能

您当前的脚本存在一些问题,这意味着您不会得到想要的结果。

首先,您的按钮是一个提交按钮,这意味着除了 ajax 调用之外,它还将执行正常提交,除非您取消默认事件(通过添加 return false; 作为脚本中的最后一行代码)。但是,将按钮类型更改为 type="button"

会更容易
<button id="loginButton" type="button" class="button button--primary">Login</button>

ajax 调用现在将更新现有页面,但是它将在现有&lt;form&gt; 元素中添加返回的部分,从而导致嵌套表单无效且不受支持。更改您的 html 以将主视图表单包装在另一个元素中

<div id="LoginFormContainer">
    @using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" }))
    {
        ....
        <button id="loginButton" type="button" class="button button--primary">Login</button>
    }
</div>

然后修改脚本更新外层元素的html

success: function (result) {
    if (result.redirectTo) {
        window.location.href = result.redirectTo;
    } else {
        $("#LoginFormContainer").html(result); // modify
    }
},

最后,您呈现动态内容,因此客户端验证将不适用于返回的表单。假设您的属性具有验证属性(例如 Userame 属性上的 [Required] 属性),您需要在加载内容后重新解析验证器

var form = $('#LoginForm');
....
} else {
    $("#LoginFormContainer").html(result);
    // reparse validator
    form.data('validator', null);
    $.validator.unobtrusive.parse(form);
}

您注意到页面上有多个表单,在这种情况下,您的 ajax 选项应该是

data: $('#LoginForm').serialize(),

或者如果您按照上面的 sn-p 声明 var form = $('#LoginForm');,那么 data: form.serialize(), 以确保您正在序列化正确的表单。

旁注:没有必要更改文本框的id 属性(默认为id=Username",您可以简单地使用

@Html.LabelFor(x => x.UserName, "User ID")
@Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text" })  

或者只是@Html.LabelFor(x =&gt; x.UserName)的属性装饰有[Display(Name = "User ID")]

【讨论】:

  • 这应该是在局部视图中显示错误的完美示例。
猜你喜欢
  • 1970-01-01
  • 2016-03-09
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 1970-01-01
相关资源
最近更新 更多