ASP.NET MVC PartialView 不发出验证标记

ASP.NET MVC PartialView doesn't emit validation markup

提问人:Zoliqa 提问时间:12/22/2011 最后编辑:Zoliqa 更新时间:2/23/2013 访问量:4433

问:

我在 MVC 3 应用程序中创建了一个部分视图。此视图具有强类型模型,如下所示:

public class ProductViewModel
{
    [Required, Display(Name = "Product price")]
    public decimal? ProductPrice
    {
        get;

        set;
    } ...
}

在我的操作方法中,我像这样调用 PartialView 方法

PartialView("ProductViewModel", products[0]);

但是在页面上,我看不到验证逻辑的任何标记,如果页面上有任何错误,则不会发生任何事情。如果我将此部分视图用作编辑器模板,它就可以工作。 任何帮助都是值得赞赏的。

编辑:更具体地说,我有一个HTML表单,我想通过ajax更新向其添加标记(如果用户单击按钮,我想向该表单添加新标记)。如果我静态地包含这些控件,我的意思是如果我在加载页面时呈现它们,验证会起作用,但是如果我通过ajax调用将控件添加到该窗体,则不会为这些控件插入验证标记。我的部分视图如下所示:

@Html.LabelFor(x => x.ProductPrice)

@Html.TextBoxFor(x => x.ProductPrice)

@Html.ValidationMessageFor(x => x.ProductPrice)

我的表格如下所示:

@using (Html.BeginForm())
{
    <div id="div_Products">
        @Html.EditorFor(x => x)
    </div>

    <input type="submit" value="Compare" />
}

上面的代码运行良好,验证有效。在服务器端,我调用了一个操作方法,如下所示:

[HttpPost]
public ActionResult InsertProduct()
{
    var newProductVM = new ProductViewModel{ ProductPrice = 789 };

    return PartialView("~/Views/Nutrition/EditorTemplates/ProductViewModel.cshtml", newProductVM);
}

我发现 MVC 引擎只有在发现控件位于表单控件内部时才会插入这些验证标记。当我尝试通过ajax调用更新我的表单控件时,MVC无法知道它们将被放置在表单元素中,这就是为什么它不会为它们发出任何验证逻辑的原因,我想。

asp.net-mvc-3 验证 数据注释 unobtrusive-javascript

评论

0赞 rfmodulator 12/22/2011
编辑器“发出”验证错误等是有道理的,而视图则不会。我们能看到您视图的代码吗?
0赞 Zoliqa 12/22/2011
问题在于,MVC 仅在发现控件位于窗体内部时才插入验证标记。问题是我想通过ajax更新将标记添加到表单控件,但是这样MVC引擎就不知道此标记将插入到表单元素中,因此它不会发出任何验证标记。
0赞 rfmodulator 12/22/2011
您可以使用一些 Html.ValidationMessageFor() 代码强制执行它。就像我说的,请告诉我们你的观点。

答:

1赞 Alexander Zeitler 12/22/2011 #1

您是否在 web.config 或视图本身中启用了不显眼的验证?

在 web.config 中:

<configuration>
    <appSettings>
        <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
    </appSettings>
</configuration>

或内部代码:

HtmlHelper.ClientValidationEnabled = true;
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;

评论

0赞 rfmodulator 12/22/2011
他的验证在编辑器中正常工作,因此这告诉我们配置是正确的。
2赞 rfmodulator 12/22/2011 #2

在“分部视图”中,添加以下内容 (C#/Razor):

@Html.ValidationMessageFor(model => model.ProductPrice)
0赞 tbddeveloper 12/22/2011 #3

使用客户端验证,可以重新验证页面加载后加载的元素。由于 MVC 现在使用 jQuery 验证,因此如果启用了客户端验证;

jQuery Validate - 在页面加载时验证字段

这可能会对你有所帮助。

10赞 Rob 1/24/2012 #4

把它放在部分视图的顶部,你会得到呈现到 html 输出中的验证消息:

if (this.ViewContext.FormContext == null) 
{
    this.ViewContext.FormContext = new FormContext(); 
}

如果您使用 ajax 添加表单字段,则可以在将新字段添加到 DOM/Page 后触发它们添加到验证中,如下所示:

$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

编辑/更新(2013年23日美联储): 我刚刚在 Visual Studio 2012 中首次破解了部分视图的 FormContext,似乎使用最新版本的 jQuery 和 Validation 等,我不需要添加 3 行 javascript(上面)即可进行验证,以便在 ajax 上动态工作,这很棒!

评论

0赞 Rob 6/16/2012
@ChrisJackson - 好吧,纯粹从高级黑盒的角度来看问题,可以公平地说,Html.ValidationMessageFor 会查找非 null FormContext - 通常使用类似 using(Html.BeginForm){ 的东西进行设置 - 如果它没有找到,那么它就不会费心渲染验证消息。我的猜测是 JS 验证需要一个表单才能正常运行,因此没有必要使用验证消息。IMO 这是 .Net 团队的疏忽。
2赞 Tom van Enckevort 2/20/2012 #5

不确定这对您来说是否仍然是一个问题,但解决方案是调用:

$.validator.unobtrusive.parse($('#your-new-form-div'));

通过 AJAX 加载窗体标记/控件后。这将分析您的新表单元素,并创建您在视图中指定的客户端验证。

评论

0赞 vbullinger 9/8/2012
不管这对他来说是否是问题,这对我来说都是一个问题。整个下午,我一直在 interwebz 的深处蹦蹦跳跳,寻找这个,知道这将是关于重新应用验证的事情。我唯一的遗憾是我只有一个赞成票。谢谢你,善良的先生,因为我现在可以停止一头扎进这堵沾满了我血的砖墙了。哦,我没有说$('#my-new-form-div'),我说$('form'),它仍然有效。仅供参考。