Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can HtmlHelper be used to create an external hyperlink?

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.)

like image 852
Logical Fallacy Avatar asked Jan 19 '12 20:01

Logical Fallacy


3 Answers

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!

like image 81
jkokorian Avatar answered Oct 15 '22 05:10

jkokorian


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>");
}
like image 33
Dan Atkinson Avatar answered Oct 15 '22 03:10

Dan Atkinson


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.

like image 27
par Avatar answered Oct 15 '22 03:10

par