【问题标题】:How do you access the model errors on the client side?您如何在客户端访问模型错误?
【发布时间】:2012-02-03 11:55:28
【问题描述】:

我不喜欢内置的 Html.ValidationSummary 助手,因为我希望在表单顶部显示一条消息,例如...

存在验证错误。无效字段已突出显示。

内置的 ValidationSummary 要么根本不输出任何内容,要么输出所有字段的列表。我只想要一个简洁的信息。

我的表单顶部有一个 div,按照我想要的方式设置样式,然后当页面加载时,我将以下方法挂接到表单...

function CheckFormForValidationErrors() 
{
    if (!$("form").valid()) 
    {
        $(".validation-notification").css("visibility", "visible");
    }
}

当客户端出现验证错误时,这非常有用。问题是客户端验证成功但服务器端验证(例如登录表单)时。如果用户输入正确的用户名和密码,则表单验证成功,但登录失败。在服务器端,我正在添加一个模型错误,如下所示......

ModelState.AddModelError(string.Empty, "Login failed");

但我不知道如何让消息显示在客户端上。如果您有更好的想法来实现我的目标,那么我愿意放弃我的想法并改变路线。我想做的事情应该不会那么难。

【问题讨论】:

    标签: jquery asp.net-mvc-3


    【解决方案1】:

    当您在视图中时,ModelState 位于 ViewData 中

     ViewData.ModelState
    

    并获取错误消息:

     foreach(string key in ViewData.ModelState.Keys)
     {
         foreach (var error in ViewData.ModelState[key].Errors)
         {
             string err = error.ErrorMessage;
         }
     }
    

    在 Razor 中,也许这会起作用(我的 Razor 生锈了)

    @if (!ViewData.ModelState.IsValid)
    {
        <ul>
        @foreach (string key in ViewData.ModelState.Keys)
        {
            @foreach (var error in ViewData.ModelState[key].Errors)
            {
                <li>@error.ErrorMessage</li>
            }
        }
        </ul>
    }
    

    【讨论】:

      【解决方案2】:

      您有无数种选择。如果您只想显示由此创建的消息:

      ModelState.AddModelError(string.Empty, "Login failed");
      

      你只需要在你的视图中:

      @Html.ValidationMessage(String.Empty)
      

      不过,这会将消息包装在 &lt;span class="field-validation-error"&gt;&lt;/span&gt; 中,但如果您愿意,可以轻松覆盖默认样式。

      但是根据您上面描述的用例,听起来您需要的只是一个静态(ish)图例,用于解释“存在验证错误。无效字段已突出显示。" 每当屏幕上出现一个或多个验证失败时。

      那么这个怎么样:

      namespace MvcApplication.Web.Extensions
      {
          public static class HtmlHelperExtensions
          {
              private const string ValidationLegendHtml = 
                  "<div class=\"validation-legend\">{0}</div>";
              private const string DefaultValidationLegend =
                  "There are validation errors. The invalid fields have been highlighted";
      
              public static MvcHtmlString ValidationLegend(
                  this HtmlHelper htmlHelper, string message = DefaultValidationLegend)
              {
                  if(htmlHelper.ViewData.ModelState.IsValid)
                  {
                      return null;
                  }
                  return new MvcHtmlString(String.Format(ValidationLegendHtml, message));
              }
          }
      }
      

      然后在视图中你只需要插入:

      @Html.ValidationLegend()    //Use the default legend message
      @Html.ValidationLegend("Something went wrong!")    //Specific message
      

      如果表单无效,这将显示图例,并且在其有效时完全不可见!

      您还需要将新扩展的命名空间添加到您的 Views/web.config(不要与根 web.config 混淆),如下所示:

      <pages pageBaseType="System.Web.Mvc.WebViewPage">
        <namespaces>
          <add namespace="System.Web.Mvc" />
          <add namespace="System.Web.Mvc.Ajax" />
          <add namespace="System.Web.Mvc.Html" />
          <add namespace="System.Web.Routing" />
      
          <!-- Add Me! -->
          <add namespace="MvcApplication.Web.Extensions"/>
        </namespaces>
      </pages>
      

      不幸的是,这不会为您提供新扩展方法的智能感知,如果这很重要,您可以选择(或另外)在 @model 声明之后立即将扩展的 using 语句添加到视图顶部,如下所示:

      @model MvcApplication.Web.Models.LoginModel
      @using MvcApplication.Web.Extensions
      

      编辑

      如果您还想支持显示此客户端,请将扩展名更改为:

      public static MvcHtmlString ValidationLegend(
          this HtmlHelper htmlHelper, string message = DefaultValidationLegend)
      {
          var tagBuilder = new TagBuilder("div");
          tagBuilder.SetInnerText(message);
          tagBuilder.AddCssClass("validation-legend");
      
          if(htmlHelper.ViewData.ModelState.IsValid)
          {
              tagBuilder.AddCssClass("hide");
          }
      
          return new MvcHtmlString(tagBuilder.ToString());
      }
      

      确保您有 .hide { display: none; } CSS 规则。

      再次编辑

      您可以让 jquery.validate 自动为您显示/隐藏图例,方法是将 errorContainer 配置设置的默认值设置为匹配图例的 CSS 类。这可以通过声明脚本包含来完成,如下所示:

      <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
              type="text/javascript"></script>
      <script type="text/javascript">
          jQuery.validator.setDefaults({ errorContainer: '.validation-legend' });
      </script>
      <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
              type="text/javascript"></script>
      

      注意在jquery.validate 脚本标签之后 而在jquery.validate.unobtrusive 脚本标签之前 的setDefaults 调用。这个顺序很重要。另请注意,任何验证错误都会显示所有 .validation-legend,因此如果您有任何具有两个不同验证图例的屏幕,您可能需要更花哨一些。

      【讨论】:

      • 我尝试了您的示例,它运行良好,但它不适用于客户端验证。如果我输入无效值,则字段会按我的意愿变为红色,但顶部没有消息。如果我尝试使用无效凭据登录,它会显示出来。我正在尝试获取一条消息以显示客户端验证错误服务器端验证错误。
      • 对不起,您编辑了您的答案,在我更改评论之前我没有看到它。我会尝试你的建议,但我认为你建立了我所缺少的联系。
      • 请查看我更新的答案,它还会在客户端错误时自动为您显示/隐藏图例!
      猜你喜欢
      • 2014-10-16
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-15
      相关资源
      最近更新 更多