In the same way that I can create an ActionLink in ASP.NET MVC that points to an action in a controller (e.g. - @Html.ActionLink("MyDisplayText", "MyAction", "MyController")
), I would like to be able to create a hyperlink with an explicitly-defined, external url.
What I'm looking for is some code like @Html.HyperLink("stackoverflow", "http://www.stackoverflow.com/")
that generates this HTML: <a href="http://www.stackoverflow.com/">stackoverflow</a>
If this isn't possible, I can always just write the HTML by hand.
(This is my first stackoverflow question. How exciting.)
A custom helper could look like this:
namespace System.Web.Mvc {
public static class HtmlHelperExtensions {
public static MvcHtmlString Hyperlink(this HtmlHelper helper, string url, string linkText) {
return MvcHtmlString.Create(String.Format("<a href='{0}'>{1}</a>", url, linkText));
}
}
}
May this be the first of many custom HtmlHelpers you use!
This question is several years old and was intended as an answer for ASP.NET MVC v2. There are probably better, nicer ways to do this now, and I would strongly suggest that you consider looking at @jkokorian's answer. This just a nice way of showing what you could do, not what you should do!
Nothing terribly new to add, but I tend to use object
for optional params on HTML helpers, and add new RouteValueDictionary(obj)
which turns them into a KVP which you can add with MergeAttributes
.
Code:
public static class HtmlHelpers {
public static MvcHtmlString ExternalLink(this HtmlHelper htmlHelper, string url, object innerHtml, object htmlAttributes = null, object dataAttributes = null) {
var link = new TagBuilder("a");
link.MergeAttribute("href", url);
link.InnerHtml = innerHtml.ToString();
link.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);
//Data attributes are definitely a nice to have.
//I don't know of a better way of rendering them using the RouteValueDictionary however.
if (dataAttributes != null) {
var values = new RouteValueDictionary(dataAttributes);
foreach (var value in values) {
link.MergeAttribute("data-" + value.Key, value.Value.ToString());
}
}
return MvcHtmlString.Create(link.ToString(TagRenderMode.Normal));
}
}
Usage in view:
Basic constructor:
@Html.ExternalLink("http://www.example.com", "Example!")
With Html attributes:
@Html.ExternalLink("http://www.example.com", "Example!", new { title = "Example" })
With HTML and data attributes:
@Html.ExternalLink("http://www.example.com", "Example!", new { target = "_blank" }, new { id = 1 })
Unit tests:
[TestMethod]
public void ExternalLink_Example_ShouldBeValid() {
//Arrange
var url = "http://www.example.com";
var innerHtml = "Example";
//Act
var actual = HtmlHelpers.ExternalLink(null, url, innerHtml);
//Assert
actual.ToString().Should().Be(@"<a href=""http://www.example.com"">Example</a>");
}
[TestMethod]
public void ExternalLink_Example_WithHtmlAttributes_ShouldBeValid() {
//Arrange
var url = "http://www.example.com";
var innerHtml = "Example";
//Act
var actual = HtmlHelpers.ExternalLink(null, url, innerHtml, new { title = "Example!", @class = "myLink", rel = "external", target = "_blank" });
//Assert
actual.ToString().Should().Be(@"<a class=""myLink"" href=""http://www.example.com"" rel=""external"" target=""_blank"" title=""Example!"">Example</a>");
}
[TestMethod]
public void ExternalLink_Example_WithDataAttributes_ShouldBeValid() {
//Arrange
var url = "http://www.example.com";
var innerHtml = "Example";
//Act
var actual = HtmlHelpers.ExternalLink(null, url, innerHtml, new { title = "Example!" }, new { linkId = 1 });
//Assert
actual.ToString().Should().Be(@"<a data-linkId=""1"" href=""http://www.example.com"" title=""Example!"">Example</a>");
}
Old question: But simple answer - not sure if this was always a solution.
@Html.RouteLink("External Link", new {}, new { href="http://www.google.com" })
does the trick nicely - although possibly a little overkill.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With