【问题标题】:ASP.NET MVC PartialView doesn't emit validation markupASP.NET MVC PartialView 不发出验证标记
【发布时间】:2012-01-26 04:01:14
【问题描述】:

我在 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 无法知道它们将被放置在表单元素中,这就是为什么它不会为它们发出任何验证逻辑的原因,我想。

【问题讨论】:

  • 编辑器“发出”验证错误等是有道理的,而视图则不会。我们可以查看您的视图的代码吗?
  • 问题是 MVC 只有在发现控件位于表单内时才会插入验证标记。问题是我想通过 ajax 更新将标记添加到表单控件,但是这样 MVC 引擎不知道该标记将被插入到表单元素中,因此它不会发出任何验证标记。
  • 你可以用一些 Html.ValidationMessageFor() 代码强制它。就像我说的,请向我们展示您的观点。

标签: asp.net-mvc-3 validation data-annotations unobtrusive-javascript


【解决方案1】:

把它放在你的局部视图的顶部,你会得到验证消息渲染到 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 年 2 月 23 日): 我刚刚在 Visual Studio 2012 中首次破解了部分视图的 FormContext,似乎使用最新版本的 jQuery 和验证等,我不需要添加 3 行 javascript(上图)进行验证通过 ajax 动态工作,这很棒!

【讨论】:

  • @ChrisJackson - 好吧,纯粹从高级黑盒的角度来看问题,可以公平地说 Html.ValidationMessageFor 寻找一个非空的 FormContext - 这通常会使用诸如 using(Html.BeginForm){ 之类的东西进行设置-如果找不到,则不会费心呈现验证消息。我的猜测是 JS 验证需要一个表单才能正常运行,因此验证消息毫无意义。 IMO 这是 .Net 团队的疏忽。
【解决方案2】:

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

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

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

【讨论】:

  • 不管对他有没有问题,对我来说都是个问题。我整个下午都在interwebz的深处寻找这个,知道这将是关于重新应用验证的事情。我唯一的遗憾是我只能投一票。谢谢你,好心的先生,因为我现在可以停止冲进这堵被我的血染红的砖墙了。哦,我没有说 $('#my-new-form-div'),我说的是 $('form'),但它仍然有效。仅供参考。
【解决方案3】:

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

jquery validate - validating a field on pageload

这可能会对你有所帮助。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

      在 web.config 中:

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

      或内部代码:

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

      【讨论】:

      • 他的验证在编辑器中工作正常,所以这告诉我们配置是正确的。
      猜你喜欢
      • 1970-01-01
      • 2014-03-27
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 2012-02-05
      • 2015-04-03
      • 2011-05-14
      • 1970-01-01
      相关资源
      最近更新 更多