0

We've recently added an extension method (string.Highlight(string target)) to wrap occurences of the target text with <span class="highlighted"></span>, and are using it for all text displayed on the page.

The initial issue we ran into was that rather than the text being wrapped in the tag, the text was wrapped in plaintext "<span clas...". We've managed to resolve this with the exception of text within a link.

<%= Html.ActionLink(linkText.Highlight(word), action) %>

This sticks the text "<span class..." into the link, which is not what we want. Is there a way to apply our highlighting class to some of the text within the link, or should we forget about it?


The extension method:

public static string Highlight(this string text, this string target)
{
    return text.Replace(target, @"<span class=""highlighted"">" + target + "</span>";
}
yoozer8
  • 7,361
  • 7
  • 58
  • 93
  • Include the source to your extension method please – n8wrl Aug 13 '12 at 16:59
  • Unfortunately `ActionLink` always encodes the text, if you do not want this to happen, you can write an extension for it: http://stackoverflow.com/questions/6063467/raw-actionlink-linktext – Matthew Aug 13 '12 at 17:01

2 Answers2

1

ActionLink (and I imagine all of the Html helper methods) HTML-encodes text for obvious security reasons (preventing XSS vulnerabilities by default).

If all you need to do is apply a CSS class, you can do it directly in the ActionLink:

<%= Html.ActionLink(word, action, null, new { @class = "highlighted" })%>

Of course, this will apply the class to the a rather than use a span. But then why do you need a span inside of the a in the first place when an a can hold a class attribute as well?

David
  • 208,112
  • 36
  • 198
  • 279
1

You could write a custom ActionLink extension method that doesn't HTML encode the text as the standard helper does:

public static MvcHtmlString UnencodedActionLink(
    this HtmlHelper htmlHelper,
    string linkText,
    string actionName
)
{
    var str = UrlHelper.GenerateUrl(null, actionName, null, null, null, null, new RouteValueDictionary(), htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
    var a = new TagBuilder("a")
    {
        InnerHtml = !string.IsNullOrEmpty(linkText) ? linkText : string.Empty
    };
    a.MergeAttribute("href", str);
    return MvcHtmlString.Create(a.ToString(TagRenderMode.Normal));
}

and then:

<%= Html.UnencodedActionLink(linkText.Highlight(word), action) %>

or even better:

public static MvcHtmlString HighlightedActionLink(
    this HtmlHelper htmlHelper,
    string linkText,
    string word,
    string actionName
)
{
    var str = UrlHelper.GenerateUrl(null, actionName, null, null, null, null, new RouteValueDictionary(), htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
    var a = new TagBuilder("a")
    {
        InnerHtml = !string.IsNullOrEmpty(linkText) ? linkText.Highlight(word) : string.Empty
    };
    a.MergeAttribute("href", str);
    return MvcHtmlString.Create(a.ToString(TagRenderMode.Normal));
}

and then:

<%= Html.HighlightedActionLink(linkText, word, action) %>
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928