Anchors with asp-controller and asp-action attribute don't get rendered as links

12,192

Solution 1

HTML code, or actually any text, returned from methods is not processed by the Razor engine, so you cannot use HTML tag helpers here.

What you can do however is call the “classic” HtmlHelper.ActionLink method (or one of the more helpful extension methods) to return a properly rendered a tag for a controller action.. Since it’s just a normal method, you can call it within your own method.

For example, you could pass in the IHtmlHelper object into your method:

@foreach (LinkNodeModel link in Model.ControlActions)
{
    link.LinkTree(@Html);
}

And then in your method, just use a ActionLink overload to create the link:

public IHtmlContent LinkTree(IHtmlHelper helper)
{
    return helper.ActionLink(Name, Action, Controller);
}

Alternatively, you can also expose those three properties on your object and write the link properly with Razor:

@foreach (LinkNodeModel link in Model.ControlActions)
{
    <a asp-controller="@link.Controller" asp-action="@link.Action">@link.Name</a>
}

Solution 2

The tag helpers, which convert <a asp-controller="$controller" asp-action="$action"> to <a href="/$controller/$action"> are opt-in as described in Introducing TagHelpers in ASP.NET MVC 6, so you'll need to configure your application to use them:

This is best placed in the _ViewImports.cshtml file, which is a new Razor file also introduced in ASP.NET 5:

@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
Share:
12,192
Thomas Andreè Wang
Author by

Thomas Andreè Wang

Working as a senior engineer at Kongsberg Gruppen in Norway

Updated on June 05, 2022

Comments

  • Thomas Andreè Wang
    Thomas Andreè Wang almost 2 years

    In this Razor syntax:

    <a asp-controller="Home" asp-action="Index">Home</a>
    
    @foreach (LinkNodeModel link in Model.ControlActions)
    {
        link.LinkTree();
    }
    

    The "Home" link renders just fine, but the manually rendered <a> strings don't get turned into a valid link.

    LinkTree() is implemented like this:

    return $"<a asp-controller=\"{Controller}\" asp-action=\"{Action}\">{Name}</a>";
    

    When I print the links with the @link.LinkTree(), the output contains a line with just the code displayed, which doesn't link.

    With @Html.Raw(link.LinkTree()) I get the links, but they are not clickable as they actually print the asp-controller/asp-action attributes to the HTMLinstead of generating the href.

    Is it possible to generate and render links like these dynamically? And if so, how?

  • Thomas Andreè Wang
    Thomas Andreè Wang about 8 years
    If i write for an example ´<a asp-controller="Home" asp-action="Index">Home</a>´directly then it works. but not if i generate that line. And the taghelper is there
  • CodeCaster
    CodeCaster about 8 years
    Uhm no, strings you generate at runtime will not be parsed by Razor, but output as-is. See poke's answer for the proper solution. Tag Helpers are for example for Content Management Systems, where the users can write more HTML-ish syntax as opposed to @Razor expressions.
  • Thomas Andreè Wang
    Thomas Andreè Wang about 8 years
    Hmm, okay, that does not really make dynamic link generation any easier in vNext. But thanks for the information, it made the base for inspiration. Is there a way to skip the whole ´@Html´ part? Guessing its used to say where you are so the links make sense to where you are going.
  • poke
    poke about 8 years
    It’s just as easy, since you just call a method instead of returning some static string with magic attributes (outside of Razor, they are like magic). The @Html is to pass the HtmlHelper instance into the method. If you get access to a HTML helper in a different way in your object, you can use that. But it’s probably better to pass it in to make sure it works. – I’ve added another alternative to my answer that creates the link directly in the view, maybe that works better for you.
  • Thomas Andreè Wang
    Thomas Andreè Wang about 8 years
    Yes just as easy is still not easier ;) i was hoping to produce a tree of links with sublinks with sublinks (eg. linked list). and to print it i was hoping to be able to take one link and print the descending tree and just place the string of links where i wanted it.