我在这里组合了一个小例子,只是为了复制问题。 我有一个强类型的局部视图 _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>
最初加载并显示在主 Index.cshtml 内的内容。
<div id="divForm">
@using (Html.BeginForm()) {
<div id="divName">
@Html.Partial("_Name")
</div>
}
</div>
字段 MyName 是必需的,并且验证是通过 MyViewModel 中的 Required 属性实施的。
namespace ValidationInPartial.ViewModels
{
public class MyViewModel
{
[Required(ErrorMessage = "Please enter a Name.")]
public string MyName { get; set; }
}
}
第一次加载页面后,如果您点击"创建"按钮并将字段留空,则验证消息"请填写名称。"会显示在该字段旁边,并且该字段本身会变成粉色,这是期望的行为。 现在通过点击“重新加载名称”链接(它会进行ajax调用 (jquery.load(...))),部分内容将被重新加载,这是控制器代码:
public PartialViewResult NameReload()
{
MyViewModel myViewModel = new MyViewModel();
ViewBag.Message = "Name Reloaded";
return 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的bug还是jquery的问题?有什么想法吗?
我也在某处读到过,ajax调用会丢失页面中的所有脚本,实际上我必须将任何javascript代码放在局部区域内,以便它们可以被再次渲染和使用。
与此同时,我找到了一个解决方法,即在局部视图中手动呈现@Html.ValidationMessageFor应该呈现的内容,即:
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="MyName"></span>
然而,这种解决方法意味着如果我们在ViewModel中更改验证的类型或验证消息,就需要修改视图中这个硬编码的html片段。
@{ ViewContext.FormContext = new FormContext(); }
- AaronLS