我不喜欢内置的Html.ValidationSummary助手,因为我希望在表单顶部显示一条消息,例如......
存在验证错误。无效字段已突出显示。
内置的ValidationSummary根本不输出任何内容或输出所有字段的列表。我只想要一个简洁的信息。
我的表单顶部有一个div,按我想要的方式设置,然后当页面加载时,我将以下方法挂钩到表单上...
function CheckFormForValidationErrors()
{
if (!$("form").valid())
{
$(".validation-notification").css("visibility", "visible");
}
}
当客户端上存在验证错误时,这非常有用。问题是客户端验证成功但服务器端验证(如登录表单)。如果用户输入正确的用户名和密码,则表单验证成功但登录失败。在服务器端,我正在添加模型错误,如此...
ModelState.AddModelError(string.Empty, "Login failed");
但我无法弄清楚如何在客户端上显示消息。如果你有更好的想法来实现我的目标,那么我愿意废弃我的想法并改变方向。我想做的事情不应该那么难。
答案 0 :(得分:4)
当您在视图中时,ModelState位于ViewData
中 ViewData.ModelState
并收到错误消息:
foreach(string key in ViewData.ModelState.Keys)
{
foreach (var error in ViewData.ModelState[key].Errors)
{
string err = error.ErrorMessage;
}
}
在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>
}
答案 1 :(得分:2)
你有很多选择。如果您只想显示由此创建的消息:
ModelState.AddModelError(string.Empty, "Login failed");
您只需在视图中使用此功能:
@Html.ValidationMessage(String.Empty)
然而,这会将消息包装在<span class="field-validation-error"></span>
中,但如果您愿意,可以轻松覆盖默认样式。
然而,根据您在上面描述的用例,您需要的只是一个静态(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(不要与root 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规则。
再次编辑
您可以通过设置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>
请注意在 jquery.validate脚本标记之后来的setDefaults调用,但之前 jquery.validate.unobtrusive脚本标记。这个顺序很重要。另请注意,任何验证错误都会显示所有.validation-legends,因此如果您有任何具有两种不同验证图例的屏幕,则可能需要更加花哨。