如何扩展Html.ValidationMessage以便我可以将图像包含为错误?

时间:2009-08-12 12:28:35

标签: .net asp.net-mvc validation

我想减少以下代码。下面的代码有效,但它不是很整洁等。

    <label for="Name">Name:</label><%= Html.TextBox("Name")%><% 
    if (!string.IsNullOrEmpty(Html.ValidationMessage("Name"))) {
        string Error = HtmlRemoval.StripTags(Html.ValidationMessage("Name")); %>
        <img src="Error.gif" alt="Error" title="<%= Error %>" /><%
    }
    %>

我已经读过我需要扩展Html帮助器,以便我可以返回一个图像而不是包含默认元素和文本错误的文本。

我似乎无法找到关于如何实现这一目标的任何文章或一般性建议。我仍然是ASP.NET MVC的新手。任何建议都将不胜感激。

7 个答案:

答案 0 :(得分:13)

你可以扩展HtmlHelper,如:

public static class CustomHtmlHelper {

  public static string ValidationImage(this HtmlHelper helper, string name) {
    if (helper.ViewData.ModelState[name] == null || helper.ViewData.ModelState[name].Errors == null) {
      return String.Empty;
    }
    TagBuilder tag = new TagBuilder("img");
    tag.Attributes.Add("src", "Error.gif");
    tag.Attributes.Add("alt", "Error");
    tag.Attributes.Add("title", helper.ViewData.ModelState[name].Errors[0].ErrorMessage);
    return tag.ToString(TagRenderMode.SelfClosing);
  }

}

然后在您的页面中导入包含扩展方法

的类
<%@ Import Namespace="CustomHtmlHelperNamespace" %>

然后将以下内容添加到您的页面中:

<label for="Name">Name:</label>
<%= Html.TextBox("Name")%>
<% Html.ValidationImage("Name") %>

有关扩展HtmlHelper的更多信息,请尝试here,但基本上这会扩展HtmlHelper,检查ViewState是否在名称中解析的值上出错(在您的情况下为“Name”),如果包含错误则生成HTML需要渲染图像。图像的title属性将包含“Name”字段的验证消息

答案 1 :(得分:1)

您可以通过创建如下所示的类来扩展Html Helper以添加方法。不是100%这就是你所要求的,但这里是:

public class HtmlHelperExtensions {

    public static string GetMeSomething(this HtmlHelper helper)
    {
        //... Do things here. ...
    }
}

一旦你有类似的东西,你可以调用Html.GetMeSomething,它将返回一个字符串或你声明你的返回类型为。

答案 2 :(得分:1)

滚动你自己的ValidationMessage帮助器来渲染图像标签可能是你最好的选择......内置帮助器会渲染一个标签,如

<span class="field-validation-error">You must specify a username.</span>

所以,如果你不打算改变它,那么你就可以使用CSS和/或jQuery技巧来完成这项工作。

我不知道如果用CSS做,但是如果你能在DIV标签中处理错误消息,你可以尝试这样的事情:

.field-validation-error
{
    background: url(x.gif) no-repeat;
    padding-left:10px;
    color: #ff0000;
}

<div style="width:10px; height:10px; overflow:hidden;">
    <%= Html.ValidationMessage("username") %>
</div>

对于10x10 gif,这将隐藏文本,但它将在一个块元素内,并且没有错误消息title /“tooltip”。不完全是最好的解决方案。我会在MVC源代码中检查ValidationMessage方法的代码,并考虑根据需要调整自己的代码,或者再次使用Javascript来做诡计。

编辑:为了好玩,我决定从MVC源代码开始测试我自己的验证消息助手。它很脏(硬编码的图像路径),但是一个工作的例子。在这种情况下,它要求您传递验证消息 - 我省略了一些代码,它可选地显示默认的内置消息。

public static string MyValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage)
{
    if (modelName == null)
        throw new ArgumentNullException("modelName");

    if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName))
        return null;

    ModelState modelState = htmlHelper.ViewData.ModelState[modelName];
    ModelErrorCollection modelErrors = (modelState == null) ? null : modelState.Errors;
    ModelError modelError = ((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors[0];

    if (modelError == null) 
        return null;

    return "<img src=\"../../Content/x.gif\" alt=\"Error\" title=\"" + validationMessage + "\" />";
}

答案 3 :(得分:1)

David Glenn的精彩回答。非常感谢您通过在Mvc中创建自定义Html助手来使我走上正轨。

但是,大卫的扩展开箱即用(在MVC3 w / Razor中)有几个问题:

  • 只返回一个字符串是行不通的;它实际上会显示字符串,标签和所有内容,除非您使用MvcHtmlString.Create()将其包装在视图(UI)上。更优雅的方法是将辅助函数的返回类型更改为MvcHtmlString。您还可以重载Helper函数以适应两种返回类型。

  • 如果您正在执行其他错误 单个模型字段,例如RegEx 检查等等,辅助方法会 失败,因为最初的“If..Then ..” 未能检查错误计数; 只是检查它是否“是空” 不够。 Errors对象会 不是空的,而是全部的 属性将在非失败 字段。

以下是为重现上述两个问题而重构的CustomHtmlHelper类,并且还注入了正确的css类名:

#Region "Imports"

Imports System.Runtime.CompilerServices

#End Region

Namespace Laddawn.Web.Mvc.Extensions

    Public Module CustomHtmlHelpers

        <Extension()>
        Public Function ValidationImage(ByVal helper As HtmlHelper, ByVal name As String) As MvcHtmlString

            If helper.ViewData.ModelState(name) Is Nothing _
            OrElse helper.ViewData.ModelState(name).Errors Is Nothing _
            OrElse helper.ViewData.ModelState(name).Errors.Count = 0 Then
                Return MvcHtmlString.Empty
            End If

            Dim tag As New TagBuilder("img")

            With tag
                .Attributes.Add("src", "/Content/Images/Mobile/alert.png")
                .Attributes.Add("alt", helper.ViewData.ModelState(name).Errors(0).ErrorMessage)
                .Attributes.Add("title", helper.ViewData.ModelState(name).Errors(0).ErrorMessage)
                .Attributes.Add("class", HtmlHelper.ValidationMessageCssClassName)
            End With

            Return MvcHtmlString.Create(tag.ToString(TagRenderMode.SelfClosing))

        End Function

    End Module

End Namespace

在您的Css文件中,创建一个类:

img.field-validation-error
{
    vertical-align:         text-bottom;
    margin-left:            5px;
}

现在你的Css也可以与按摩css分开操作图像。

注意:不要忘记更改图像路径以满足项目的需要。这是另一个可能为imagePath添加附加参数的区域,如果没有传入,则在helper方法中使用默认值。

为VB版本道歉(对于C#开发人员),我当前的项目都是VB / NET,如果你想使用上面的代码,只需在Telerik上使用转换器(http://converter.telerik.com/

答案 4 :(得分:0)

不幸的是,我的自定义验证图像助手类不适用于客户端验证。

如果有人想对可以/将支持客户端验证的版本进行破解,那么请注意! :)

答案 5 :(得分:0)

扩展Ed的答案,这是可以使用模型:

public static MvcHtmlString ValidationImageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        string propertyName = ExpressionHelper.GetExpressionText(expression);
        string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName));

        if (helper.ViewData.ModelState[name] == null || 
            helper.ViewData.ModelState[name].Errors == null || 
            helper.ViewData.ModelState[name].Errors.Count == 0)
        {
            return MvcHtmlString.Empty;
        }

        TagBuilder tag = new TagBuilder("span");
        tag.Attributes.Add("class", "field-validation-error");
        tag.Attributes.Add("data-valmsg-for", name);
        tag.Attributes.Add("data-valmsg-replace", "true");
        return MvcHtmlString.Create(tag.ToString(TagRenderMode.SelfClosing));
    }

我正在渲染到一个跨度......就像MVC渲染它一样。我在CSS类中设置了背景图像。例如:

@Html.ValidationImageFor(x => x.FieldNameHere)

HTH

答案 6 :(得分:0)

最好的是MVC开发人员将ModelError.ErrorMessage的类型更改为MvcHtmlString或其在.NET4中的新对应项(HtmlString)