views:

1239

answers:

3

I would like to reduce the following code. The below code works, however it is not very tidy etc.

    <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 %>" /><%
    }
    %>

I have read that I need to extend the Html helper so that I can return an image instead of the text containing the default element and textual error.

I can't seem to find any articles or general advice on how I would accomplish this. I am still very new to ASP.NET MVC. Any advice would be greatly appreciated.

+1  A: 

You can extend the Html Helper to add a method by making a class like below. Not 100% this is what you're asking, but here goes:

public class HtmlHelperExtensions {

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

Once you have something like that, you can call Html.GetMeSomething, and it will return a string or whatever you declare your return type as.

Jimmeh
That should be a static method.
David G
You're right, editted. Thanks.
Jimmeh
+1  A: 

Rolling you own ValidationMessage helper to render an image tag may be your best bet... The built-in helper will render a tag such as

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

so if you aren't going to change this you're left to CSS and/or jQuery tricks to do the dirty work.

I'm not aware of a pure use if CSS to do your job, but if you can handle having your error message span within a DIV tag, you could try something like:

.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>

For a 10x10 gif, this will hide the text, but it will be within a block element and without your error message title/"tooltip." Not exactly the best solution. I would check the code for the ValidationMessage method in the MVC source and consider adapting your own to render it exactly as needed, or again, there's Javascript to do the trickery.

Edit: Just for fun I decided to test my own Validation Message helper, starting from the MVC source code. It's dirty (hard-coded path to image), but a working example. In this case it requires you to pass in the validation message - I've omitted some code where it optionally displays the default built-in message.

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 + "\" />";
}
Kurt Schindler
+8  A: 

You can extend HtmlHelper like:

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);
  }

}

Then in your page import the class containing the extension method

<%@ Import Namespace="CustomHtmlHelperNamespace" %>

Then add the following to your page:

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

For more on extending HtmlHelper try here but basically this extends HtmlHelper, checks the ViewState for a an error on the value parsed in name ("Name" in your case) and if it contains an error generates the HTML needed to render the image. The title attribute for the image will contain the validation message for field "Name"

David G