Reputation: 23763
I have two questions:
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?
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:
Span text
How can I put tags inside of the anchor tag in ASP.NET MVC?
Upvotes: 179
Views: 186019
Reputation: 189
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>"))
Upvotes: 0
Reputation: 10088
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>
Upvotes: 3
Reputation: 215
Please try below Code that may help you.
@Html.ActionLink(" SignIn", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" ,**@class="glyphicon glyphicon-log-in"** })
Upvotes: 0
Reputation: 2684
My solution using bootstrap components:
<a class="btn btn-primary" href="@Url.Action("resetpassword", "Account")">
<span class="glyphicon glyphicon-user"></span> Reset Password
</a>
Upvotes: 0
Reputation: 238
This has always worked well for me. It's not messy and very clean.
<a href="@Url.Action("Index", "Home")"><span>Text</span></a>
Upvotes: 7
Reputation: 36
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);
}
}
Upvotes: 1
Reputation: 3640
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")
Upvotes: 0
Reputation: 806
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
Upvotes: 1
Reputation: 15360
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>
Upvotes: 350
Reputation: 9051
Here is (low and dirty) workaround in case you need to use ajax or some feature which you cannot use when making link manually (using tag):
<%= Html.ActionLink("LinkTextToken", "ActionName", "ControllerName").ToHtmlString().Replace("LinkTextToken", "Refresh <span class='large sprite refresh'></span>")%>
You can use any text instead of 'LinkTextToken', it is there only to be replaced, it is only important that it does not occur anywhere else inside actionlink.
Upvotes: 16
Reputation: 532465
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();
}
Upvotes: 16
Reputation: 126547
Just use Url.Action
instead of Html.ActionLink
:
<li id="home_nav"><a href="<%= Url.Action("ActionName") %>"><span>Span text</span></a></li>
Upvotes: 13