显示与父页面上的错误MVC局部视图 [英] Display mvc partial view with errors on parent page

查看:183
本文介绍了显示与父页面上的错误MVC局部视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多种形式,各自的部分的页面。我想张贴在提交每个部分。如果有错误,我要验证错误在部分显示为主要页面,即我不希望只看到部分它自己的页面上,如果有错误的一部分。我是正确地说这种行为是唯一可能与阿贾克斯的帖子?我怎么会返回模型状态错误,而一个ajax后,只是一个正常的表单提交?

编辑:
仍然能看到它自己的页

这部分

部分 -

@using(Html.BeginForm(登录,帐户,FormMethod.Post,新{ID =LoginForm的}))
{
    @ Html.ValidationMessage(InvalidUserNamePassword)
    <字段集类=字段集>
        < D​​IV>
            <标签=的形式,现场的user_id>用户ID< /标签>
            <跨度>
                @ Html.TextBoxFor(X => x.Username,新{@class =表单field__input表单field__input - 文本,@id =的形式,现场的user_id})
            < / SPAN>
        < / DIV>
    < /字段集>
    < D​​IV CLASS =表单field__button>
        <按钮ID =loginButton类型=提交级=按钮按钮 - 初级>登录和LT; /按钮>
    < / DIV>
}<脚本>
    $('#loginButton')。点击(函数(){
        $阿贾克斯({
            键入:POST,
            网址:'@ Url.Action(登录,帐户),
            数据:$('形式')序列化()。
            成功:函数(结果){
                如果(result.redirectTo){
                    window.location.href = result.redirectTo;
                }其他{
                    $(#LoginForm的)HTML(结果);
                }
            },
            错误:函数(){
                $(#LoginForm的)HTML(结果);
            }
        });
    });
< / SCRIPT>

控制器 -

[HttpPost]
公众的ActionResult登录(LoginModel模型)
{
    如果(!ModelState.IsValid)
    {
        返回PartialView(〜/查看/帐号/ _Login.cshtml模型);
    }
    返回JSON(新{redirectTo = Url.Action(指数,档案)});
}


解决方案

是的,你是在说正确的这种行为只可能有一个ajax后

有与您当前的脚本,这意味着你不会得到预期的效果了一些问题。

首先你的按钮是一个提交按钮,这意味着它会做除了Ajax调用,除非你取消默认事件(正常提交加入返回false; 作为code的脚本中的最后一行)。然而,它会更容易只是改变按钮类型,以键入=按钮

<按钮ID =loginButton类型=按钮级=按钮按钮 - 初级>登录&LT ; /按钮>

AJAX调用现在将更新现有的页面,但它会增加返回的部分内现有的<形式> 导致嵌套形式的元素,它是无效的HTML和不支持。改变你的HTML来包装主要观点形式的另一个元素

< D​​IV ID =LoginFormContainer>
    @using(Html.BeginForm(登录,帐户,FormMethod.Post,新{ID =LoginForm的}))
    {
        ....
        <按钮ID =loginButton类型=按钮级=按钮按钮 - 初级>登录和LT; /按钮>
    }
< / DIV>

再修改脚本来更新外元素的HTML

成功:函数(结果){
    如果(result.redirectTo){
        window.location.href = result.redirectTo;
    }其他{
        $(#LoginFormContainer)HTML(结果); //修改
    }
},

最后,渲染的动态内容,以便客户端验证不会为返回的形式工作。假设你的属性有验证属性(例如在的userame 属性 [必需] 属性),则需要重新分析加载内容后验证

变种形式= $('#LoginForm的');
....
}其他{
    $(#LoginFormContainer)HTML(结果);
    //重新分析验证
    form.data('验证',NULL);
    $ .validator.unobtrusive.parse(表);
}

您注意的是,你在页面上多种形式,在这种情况下,你的Ajax选项应该是

数据:$('#LoginForm的')序列化()

如果您的申报变种形式= $('#LoginForm的'); 按上面的片段,然后数据:form.serialize( ),以确保您的序列正确的形式。

边注:有没有真正的需要更改 ID 文本框(这将是 ID =用户名的属性默认情况下,你可以简单地使用

@ Html.LabelFor(X => x.UserName,用户ID)
@ Html.TextBoxFor(X => x.Username,新{@class =表单field__input表单field__input - 文本})

或只是 @ Html.LabelFor(X => x.UserName)属性的装饰有 [显示(名称=用户ID)]

I have a page with multiple forms, each as a partial. I want to post each partial on submit. If there are errors, I want the validation errors to show in the partial as part of the main page i.e. I don't want to just see the partial on it's own page if there are errors. Am I correct in saying this behavior is only possible with an ajax post? How would I return the model state errors WITHOUT an ajax post, just a normal form post?

Edit: Still seeing the partial on it's own page

Partial -

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

Controller -

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

解决方案

Yes, you are correct in saying this behavior is only possible with an ajax post.

There are a few problems with your current script meaning that you will not get the desired results.

Firstly your button is a submit button meaning that it will do a normal submit in addition to the ajax call unless you cancel the default event (by adding return false; as the last line of code in your script). However it would be easier to just change the button type to type="button"

<button id="loginButton" type="button" class="button button--primary">Login</button>

The ajax call will now update the existing page, however it will add the returned partial inside the existing <form> element resulting in nested forms which is invalid html and not supported. Change your html to wrap the main views form in another element

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

and then modify the script to update the html of the outer element

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

Finally, your rendering dynamic content so client side validation will not work for the returned form. Assuming your properties have validation attributes (for example the [Required] attribute on the Userame property), you need to reparse the validator after loading the content

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

You noted that you have multiple forms on the page, in which case your ajax options should be

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

or if your declare var form = $('#LoginForm'); as per the above snippet, then data: form.serialize(), to ensure you are serializing the correct form.

Side note: There is no real need to change the id attribute of the textbox (it will be id=Username" by default and you can simply use

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

or just @Html.LabelFor(x => x.UserName) of the property is decorated with [Display(Name = "User ID")]

这篇关于显示与父页面上的错误MVC局部视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆