MVC 3 Razor @Html.ValidationMessageFor 无法通过 jquery.load() 部分加载 [英] MVC 3 Razor @Html.ValidationMessageFor not working in partial loaded via jquery.load()

查看:25
本文介绍了MVC 3 Razor @Html.ValidationMessageFor 无法通过 jquery.load() 部分加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里整理了一个小例子只是为了重现这个问题.我有一个强类型的局部视图 _Name.cshtml:

@model ValidationInPartial.ViewModels.MyViewModel<h2>@ViewBag.Message</h2><字段集><legend>名字</legend><div class="editor-label">@Html.LabelFor(model => model.MyName)

<div class="editor-field">@Html.EditorFor(model => model.MyName)@Html.ValidationMessageFor(model =>model.MyName)

<a href="#" id="reload">重新加载名称</a><p><输入类型=提交"值=创建"/></p></fieldset><script type="text/javascript">$(document).ready(function () {$("#reload").click(function () {$("#divName").load("Home/NameReload");});});

最初加载并显示在主 Index.cshtml 中

@using (Html.BeginForm()) {<div id="divName">@Html.Partial("_Name")

}

字段 MyName 为必填项,验证通过 MyViewModel 中的 Required 属性实现

命名空间 ValidationInPartial.ViewModels{公共类 MyViewModel{[必填(ErrorMessage = "请输入名称.")]公共字符串 MyName { 获取;放;}}}

第一次加载页面后,如果您单击创建"按钮,将字段留空,则会显示验证消息请输入名称".显示在字段旁边,字段本身变成粉红色,这是预期的行为.现在通过单击重新加载名称"链接,进行 ajax 调用 (jquery.load(...)),重新加载部分,这是控制器代码:

public PartialViewResult NameReload(){MyViewModel myViewModel = new MyViewModel();ViewBag.Message = "名称重新加载";返回 PartialView("_Name", myViewModel);}

这一次,如果您单击创建"按钮将字段留空,则字段旁边不会出现验证消息,尽管该字段会变为粉红色.事实证明,当重新加载部分时,@Html.ValidationMessageFor 不会像第一次那样呈现验证消息.

这是我使用的jquery文件

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

我想知道这是否是 Razor 引擎呈现 @Html.ValidationMessageFor 的方式中的错误,还是 jquery 的问题?知道为什么会这样吗?

我还在某处读到 ajax 调用会丢失页面的所有脚本,实际上我必须将任何 javascript 代码保留在部分中,以便它们可以再次呈现和使用.

与此同时,我找到了一种解决方法,即在部分中手动呈现应该由@Html.ValidationMessageFor 呈现的内容:

然而,这种解决方法意味着,如果我们更改验证类型或仅更改 ViewModel 中的 Required 属性内的验证消息,我们需要修改视图中的这段硬编码的 html.

解决方案

@NickBork 在这里有一个很好的答案.关键是ASP.NET的MVC渲染引擎如果认为没有表单,是不会输出验证脚本的.给出的示例是将其放入表单然后从中选择 HTML 的内部部分,这实际上是将表单的外部包装器扔掉.

还有另一种方法可以让您获得视图:

ViewContext.FormContext = new FormContext();

使用这种方法,实际上不会有 FORM 代码输出,但会有验证标记.

谢谢,约翰

I have put together a small example here just to replicate the problem. I have a strongly typed partial view _Name.cshtml:

@model ValidationInPartial.ViewModels.MyViewModel

<h2>@ViewBag.Message</h2>

    <fieldset>
        <legend>Name</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.MyName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.MyName)
            @Html.ValidationMessageFor(model => model.MyName)
        </div>

        <a href="#" id="reload">Reload Name</a>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<script type="text/javascript">
    $(document).ready(function () {
        $("#reload").click(function () {
            $("#divName").load("Home/NameReload");
        });
    });
</script>

that is initially loaded and displayed inside the main Index.cshtml

<div id="divForm">
    @using (Html.BeginForm()) {

        <div id="divName">
            @Html.Partial("_Name")
        </div>
    }
</div>

The field MyName is required and validation is implemented through Required attribute in MyViewModel

namespace ValidationInPartial.ViewModels
{
    public class MyViewModel
    {
        [Required(ErrorMessage = "Please enter a Name.")]
        public string MyName { get; set; }
    }
}

After the page is loaded the first time, if you click the Create button leaving the field empty the validation message "Please enter a Name." shows beside the field and the field itself turns pink, which is the expected behaviour. Now by clicking the "Reload Name" link, which makes an ajax call (jquery.load(...)), the partial is reloaded, here is controller code:

public PartialViewResult NameReload()
{
    MyViewModel myViewModel = new MyViewModel();
    ViewBag.Message = "Name Reloaded";
    return PartialView("_Name", myViewModel);
}

This time if you click the Create button leaving the field empty the validation message does not appear beside the field, although the field turns pink. It turns out that when reloading the partial the @Html.ValidationMessageFor doesn't render the validation message as the first time.

Here is the jquery files I use

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

I wonder if this is a bug in the way the Razor engine renders the @Html.ValidationMessageFor or is that a problem with jquery? Any idea why this happens?

I have also read somewhere that the ajax call looses all the scripts for the page, in fact I have to keep any javascript code inside the partial so that they can be rendered and used again.

In the meantime I found a workaround which is to manually render in the partial what was supposed to be rendered by @Html.ValidationMessageFor which is:

<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="MyName"></span>

However this workaround means that if we change the type of validation or just the validation message inside the Required attribute in the ViewModel, we need to modify this hard-coded piece of html in the view.

解决方案

@NickBork has a great answer here. The key is that ASP.NET's MVC rendering engine does not output the validation script if it doesn't think that there is a form. The example given hacks it buy putting in a form and then selection an inner section of HTML from was was returned, essentially throwing the outer wrapper of the form away.

There is another method so that you can just get your view:

ViewContext.FormContext = new FormContext();

With this method, there won't actually be FORM code output, but the validation markup will be there.

Thanks, John

这篇关于MVC 3 Razor @Html.ValidationMessageFor 无法通过 jquery.load() 部分加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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