2009-08-12 25 views
3

我想减少下面的代码。下面的代码工作,但它是不是很整齐等如何扩展Html.ValidationMessage,以便将图像包含为错误?

<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仍然很陌生。任何建议将不胜感激。

回答

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的名称解析错误(在您的案例中的“名称”),如果它包含错误生成呈现图像所需的HTML。图像的标题属性将包含字段“名称”的验证消息。

1

您可以扩展Html Helper来添加一个类,如下所示。不是100%,这是你在问什么,但这里有云:

public class HtmlHelperExtensions { 

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

一旦你有类似的东西,你可以打电话Html.GetMeSomething,它会返回一个字符串或任何你声明的返回类型。

+0

这应该是一个静态方法。 – 2009-08-12 12:58:25

+0

你是对的,编辑。谢谢。 – Jimmeh 2009-08-12 13:07:04

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,这将隐藏文本,但它将位于块元素中,并且没有错误消息标题/“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 + "\" />"; 
} 
1

David Glenn很好的回答。非常感谢在Mvc中创建自定义Html帮助程序,让我走上正轨。

但是,也有与大卫的扩展了几个问题,开箱即用(在MVC3 W /剃刀):

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

  • 如果您在 做其他错误模式单一领域,如正则表达式 检查等,辅助方法将 失败,因为最初的“If..Then ..” 未能检查错误计数; 只是检查它是否为“空” 不够。错误对象将 不为空,但它的所有 属性将在非失败的 字段中。

所以下面是重构,以适应上述两个问题的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和使用默认的助手方法,如果一个不通过。 VB/NET,如果你想使用上面的代码,只需在Telerik使用转换器(http://converter.telerik.com/

0

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

如果有人想在可以/将支持客户端验证的版本中进行破解,那就试试吧! :)

0

扩展在埃德的答案,这是因此它可以使用模型工作:

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

0

最好将是MVC开发改变ModelError.ErrorMessage的类型的MvcHtmlString或在其.NET4新对应物(HtmlString)