Putting HTML inside Html.ActionLink(), plus No Link Text?

C#.Netasp.net MvcActionlink

C# Problem Overview


I have two questions:

  1. I'm wondering how I can display no link text when using Html.ActionLink() in an MVC view (actually, this is Site.Master).

There is not an overloaded version that does not allow link text, and when I try passing in just a blank string, the compiler tells me it needs a non-empty string.

How can I fix this?

  1. I need to put <span> tags within the anchor tag, but it's not working with Html.ActionLink();. I'd like to see the following output:

  2. Span text

How can I put tags inside of the anchor tag in ASP.NET MVC?

C# Solutions


Solution 1 - C#

Instead of using Html.ActionLink you can render a url via Url.Action

<a href="<%= Url.Action("Index", "Home") %>"><span>Text</span></a>
<a href="@Url.Action("Index", "Home")"><span>Text</span></a>

And to do a blank url you could have

<a href="<%= Url.Action("Index", "Home") %>"></a>
<a href="@Url.Action("Index", "Home")"></a>

Solution 2 - C#

A custom HtmlHelper extension is another option. Note: ParameterDictionary is my own type. You could substitute a RouteValueDictionary but you'd have to construct it differently.

public static string ActionLinkSpan( this HtmlHelper helper, string linkText, string actionName, string controllerName, object htmlAttributes )
{
    TagBuilder spanBuilder = new TagBuilder( "span" );
    spanBuilder.InnerHtml = linkText;

    return BuildNestedAnchor( spanBuilder.ToString(), string.Format( "/{0}/{1}", controllerName, actionName ), htmlAttributes );
}

private static string BuildNestedAnchor( string innerHtml, string url, object htmlAttributes )
{
    TagBuilder anchorBuilder = new TagBuilder( "a" );
    anchorBuilder.Attributes.Add( "href", url );
    anchorBuilder.MergeAttributes( new ParameterDictionary( htmlAttributes ) );
    anchorBuilder.InnerHtml = innerHtml;

    return anchorBuilder.ToString();
}

Solution 3 - C#

Solution 4 - C#

Just use Url.Action instead of Html.ActionLink:

<li id="home_nav"><a href="<%= Url.Action("ActionName") %>"><span>Span text</span></a></li>

Solution 5 - C#

This has always worked well for me. It's not messy and very clean.

<a href="@Url.Action("Index", "Home")"><span>Text</span></a>

Solution 6 - C#

I ended up with a custom extension method. Its worth noting, when trying to place HTML inside of an Anchor object, the link text can be either to the left, or to the right of the inner HTML. For this reason, I opted to provide parameters for left and right inner HTML - the link text is in the middle. Both left and right inner HTML are optional.

Extension Method ActionLinkInnerHtml:

	public static MvcHtmlString ActionLinkInnerHtml(this HtmlHelper helper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues = null, IDictionary<string, object> htmlAttributes = null, string leftInnerHtml = null, string rightInnerHtml = null)
	{
		// CONSTRUCT THE URL
		var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
		var url = urlHelper.Action(actionName: actionName, controllerName: controllerName, routeValues: routeValues);

		// CREATE AN ANCHOR TAG BUILDER
		var builder = new TagBuilder("a");
		builder.InnerHtml = string.Format("{0}{1}{2}", leftInnerHtml, linkText, rightInnerHtml);
		builder.MergeAttribute(key: "href", value: url);

		// ADD HTML ATTRIBUTES
		builder.MergeAttributes(htmlAttributes, replaceExisting: true);

		// BUILD THE STRING AND RETURN IT
		var mvcHtmlString = MvcHtmlString.Create(builder.ToString());
		return mvcHtmlString;
	}

Example of Usage:

Here is an example of usage. For this example I only wanted the inner html on the right side of the link text...

@Html.ActionLinkInnerHtml(
	linkText: "Hello World"
    	, actionName: "SomethingOtherThanIndex"
    	, controllerName: "SomethingOtherThanHome"
    	, rightInnerHtml: "<span class=\"caret\" />"
    	)

Results:

this results in the following HTML...

<a href="/SomethingOtherThanHome/SomethingOtherThanIndex">Hello World<span class="caret" /></a>

Solution 7 - C#

I thought this might be useful when using bootstrap and some glypicons:

<a class="btn btn-primary" 
    href="<%: Url.Action("Download File", "Download", 
    new { id = msg.Id, distributorId = msg.DistributorId }) %>">
    Download
    <span class="glyphicon glyphicon-paperclip"></span>
</a>

This will show an A tag, with a link to a controller, with a nice paperclip icon on it to represent a download link, and the html output is kept clean

Solution 8 - C#

Here is an uber expansion of @tvanfosson's answer. I was inspired by it and decide to make it more generic.

    public static MvcHtmlString NestedActionLink(this HtmlHelper htmlHelper, string linkText, string actionName,
        string controllerName, object routeValues = null, object htmlAttributes = null,
        RouteValueDictionary childElements = null)
    {
        var htmlAttributesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        
        if (childElements != null)
        {
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);

            var anchorTag = new TagBuilder("a");
            anchorTag.MergeAttribute("href",
                routeValues == null
                    ? urlHelper.Action(actionName, controllerName)
                    : urlHelper.Action(actionName, controllerName, routeValues));
            anchorTag.MergeAttributes(htmlAttributesDictionary);
            TagBuilder childTag = null;

            if (childElements != null)
            {
                foreach (var childElement in childElements)
                {
                    childTag = new TagBuilder(childElement.Key.Split('|')[0]);
                    object elementAttributes;
                    childElements.TryGetValue(childElement.Key, out elementAttributes);

                    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(elementAttributes);

                    foreach (var attribute in attributes)
                    {
                        switch (attribute.Key)
                        {
                            case "@class":
                                childTag.AddCssClass(attribute.Value.ToString());
                                break;
                            case "InnerText":
                                childTag.SetInnerText(attribute.Value.ToString());
                                break;
                            default:
                                childTag.MergeAttribute(attribute.Key, attribute.Value.ToString());
                                break;
                        }
                    }
                    childTag.ToString(TagRenderMode.SelfClosing);
                    if (childTag != null) anchorTag.InnerHtml += childTag.ToString();
                }                    
            }
            return MvcHtmlString.Create(anchorTag.ToString(TagRenderMode.Normal));
        }
        else
        {
            return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributesDictionary);
        }
    }

Solution 9 - C#

It's very simple.

If you want to have something like a glyphicon icon and then "Wish List",

<span class="glyphicon-heart"></span> @Html.ActionLink("Wish List (0)", "Index", "Home")

Solution 10 - C#

Please try below Code that may help you.

 @Html.ActionLink(" SignIn", "Login", "Account", routeValues: null, htmlAttributes: new {  id = "loginLink" ,**@class="glyphicon glyphicon-log-in"** }) 

Solution 11 - C#

My solution using bootstrap components:

<a class="btn btn-primary" href="@Url.Action("resetpassword", "Account")">
    <span class="glyphicon glyphicon-user"></span> Reset Password
</a>

Solution 12 - C#

please try this code:

@Html.Raw(@Html.ActionLink("text", "ActionName", "ControllerName", null, new { area = "Home" }).ToHtmlString().Replace("text", "<i class='fa fa-car sub-icon-mg' aria-hidden='true'></i> <span class='mini-sub-pro'>Link Text</span>"))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMegaMattView Question on Stackoverflow
Solution 1 - C#DavidView Answer on Stackoverflow
Solution 2 - C#tvanfossonView Answer on Stackoverflow
Solution 3 - C#Goran ObradovicView Answer on Stackoverflow
Solution 4 - C#Craig StuntzView Answer on Stackoverflow
Solution 5 - C#dbarthView Answer on Stackoverflow
Solution 6 - C#barrypickerView Answer on Stackoverflow
Solution 7 - C#Terry KernanView Answer on Stackoverflow
Solution 8 - C#william-kidView Answer on Stackoverflow
Solution 9 - C#DanKodiView Answer on Stackoverflow
Solution 10 - C#AhsanulView Answer on Stackoverflow
Solution 11 - C#Carlos ToledoView Answer on Stackoverflow
Solution 12 - C#RainyTearsView Answer on Stackoverflow