您如何访问客户端的模型错误?

oli*_*iwa 5 jquery asp.net-mvc-3

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

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

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

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

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

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

ModelState.AddModelError(string.Empty, "Login failed");
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*ork 7

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

 ViewData.ModelState
Run Code Online (Sandbox Code Playgroud)

并获取错误消息:

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

在 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>
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*ner 3

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

ModelState.AddModelError(string.Empty, "Login failed");
Run Code Online (Sandbox Code Playgroud)

在你看来,你只需要这个:

@Html.ValidationMessage(String.Empty)
Run Code Online (Sandbox Code Playgroud)

然而,这会将消息包装在 a 中,<span class="field-validation-error"></span>但如果您愿意,可以轻松覆盖默认样式。

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

那么这个怎么样:

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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在视图中您只需插入:

@Html.ValidationLegend()    //Use the default legend message
@Html.ValidationLegend("Something went wrong!")    //Specific message
Run Code Online (Sandbox Code Playgroud)

如果表单无效,这将显示图例,而当表单有效时,将完全不可见!

您还需要将新扩展的命名空间添加到您的视图/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>
Run Code Online (Sandbox Code Playgroud)

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

@model MvcApplication.Web.Models.LoginModel
@using MvcApplication.Web.Extensions
Run Code Online (Sandbox Code Playgroud)

编辑

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

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());
}
Run Code Online (Sandbox Code Playgroud)

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

再次编辑

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

<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>
Run Code Online (Sandbox Code Playgroud)

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