2

I'm creating a custom helper to create image links as follows:

    public static MvcHtmlString ImageLink(this HtmlHelper helper, string imageUrl, string imageAlt, string linkUrl, string linkTitle, string linkTarget)
{
    //create the image object
    var img = new TagBuilder("img");

    //add its attributes
    img.MergeAttribute("src", imageUrl);
    img.MergeAttribute("alt", imageAlt);

    //create the link
    var link = new TagBuilder("a");

    //add its attributes
    link.MergeAttribute("href", linkUrl);
    link.MergeAttribute("title", linkTitle);
    link.MergeAttribute("target", linkTarget);

    //set the inner html of the link to that of the img
    link.InnerHtml = img.ToString();

    //finally return the link tag
    return MvcHtmlString.Create(link.ToString(TagRenderMode.EndTag));
}

But, when I use it, it doesn't render anything at all. When I change the last line to:

return MvcHtmlString.Create(link.ToString(TagRenderMode.SelfClosing));

It only renders the a tag and encapsulates the text just beyond the statement for example:

Hello @Html.ImageLink("...params") world

The result here is that the 'world' text is wrapped in the anchor, but there's no image. I didn't even realise it could do this, since the word 'world' is not part of the helper statement.

I finally changed the final statement to:

return MvcHtmlString.Create(link.ToString(TagRenderMode.Normal));

this worked, but my questions is why? I thought EndTag made more sense especially when looking at the description given by the Intellisense for that option.

1 Answer 1

3

Last 2 lines of your code should be:

        link.InnerHtml = img.ToString(TagRenderMode.SelfClosing);

        return MvcHtmlString.Create(link.ToString());

You don't need TagRenderMode.Normal as it's the default mode. To use it in your View, you'd do this:

@Html.ImageLink("/images/test.jpg", "testalt", "http://testlink", "linktitle", "linktarget")

I thought EndTag made more sense

You may think so, but TagRenderMode.EndTag only renders the closing tag. TagRenderMode.Normal is what you're after as it creates a normal HTML tag and allows InnerHtml.

Sign up to request clarification or add additional context in comments.

2 Comments

One question. Wouldn't it make sense that when you render the link tag that you should use TagRenderMode.EndTag since you want the link to have an explicit </a> ending?
I can see what you mean, but the default behaviour of tagbuilder is to create a html tag with an open and end tag. Explicitly seeing the mode to endtag will force it to only create the end tag. It can be useful for when you want to create a big lump of html in your code then specify a closing tag at the end. Hope that makes sense

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.