337

In the latest (RC1) release of ASP.NET MVC, how do I get Html.ActionLink to render as a button or an image instead of a link?

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
  • 13
    With MVC 3.0 you can try this way Home More info, Try this http://mycodingerrors.blogspot.com/2012/08/actionlink-with-image-in-aspnet-mvc-3.html – lasantha Aug 31 '12 at 06:26
  • Having just spent a few hours doing this "properly" (e.g. by extending `AjaxHelper` with an `ActionButton`) I thought I would share it below. – iCollect.it Ltd Jan 27 '14 at 09:13
  • 7
    It's hilarious to me that seven years later, this question is still getting upvotes. Apparently in 2016 there's still no simple, intuitive way to do this. – Ryan Lundy Jan 19 '16 at 16:05

23 Answers23

357

I like to use Url.Action() and Url.Content() like this:

<a href='@Url.Action("MyAction", "MyController")'>
    <img src='@Url.Content("~/Content/Images/MyLinkImage.png")' />
</a>

Strictly speaking, the Url.Content is only needed for pathing is not really part of the answer to your question.

Thanks to @BrianLegg for pointing out that this should use the new Razor view syntax. Example has been updated accordingly.

jslatts
  • 9,307
  • 5
  • 35
  • 38
334

Late response but you could just keep it simple and apply a CSS class to the htmlAttributes object.

<%= Html.ActionLink("Button Name", "Index", null, new { @class="classname" }) %>

and then create a class in your stylesheet

a.classname
{
    background: url(../Images/image.gif) no-repeat top left;
     display: block;
     width: 150px;
     height: 150px;
     text-indent: -9999px; /* hides the link text */
}
Mark
  • 6,051
  • 2
  • 26
  • 25
  • 2
    This works perfectly for me, though you may need to replace null with a routeValues object depending on where you are linking to. – David Conlisk Oct 13 '09 at 09:51
  • 1
    How do you handle the Button name string you assign in the action link parameter then. This did not work for me. – ZVenue Jul 22 '11 at 18:06
  • 1
    Same problem, for me too, the linkText param can't be null or and empty string however I'm looking for an image button replacment. – Ant Swift Sep 13 '11 at 18:08
  • For SEO and Accessibility you would need the link button text.. i've updated the CSS in the question to handle this... – Mark Oct 14 '11 at 09:26
  • It works perfect but this button image doesnt appears in the print of the webpage. – kk1076 Jan 04 '13 at 06:26
  • 5
    that is bad in all sorts of ways, it dose not work in all browsers, and you are using a side effect as functionality. witch makes it a very bad practice don't use it. Just because it works it does not make it a good solution. – Pedro.The.Kid May 28 '14 at 14:49
  • @Pedro - How about you suggest a useful alternative as I'm sure it DOSE in fact work in all browsers and additionally keeps the HTML lean and semantic. Care to elaborate? – Mark Jun 04 '14 at 11:15
  • 4
    @Mark - jslatts solution is the correct one and no it wont work in IE11 and just because it work's in the current browsers it is a very bad practice as you are using a side effect as functionality and if the implementation changes the side effect WILL stop working. – Pedro.The.Kid Jun 05 '14 at 10:05
  • 1
    Instead of hiding the button text using the `text-indent: -9999px;` why not do this: `<%= Html.ActionLink(" ", "Index", null, new { @class="classname" }) %>` Using a space for the name. – Trevor Nestman Aug 17 '16 at 16:21
96

Borrowing from Patrick's answer, I found that I had to do this:

<button onclick="location.href='@Url.Action("Index", "Users")';return false;">Cancel</button>

to avoid calling the form's post method.

DevDave
  • 6,700
  • 12
  • 65
  • 99
50

Call me simplistic, but I just do:

<a href="<%: Url.Action("ActionName", "ControllerName") %>">
    <button>Button Text</button>
</a>

And you just take care of the hyperlink highlight. Our users love it :)

agAus
  • 675
  • 1
  • 7
  • 11
  • 1
    @Ben one reason this doesn't have many votes is it was answered so much later than other answers. I was about to vote it up but tested out what @Slider345 said and can confirm this doesn't work as desired in IE 7 or 8. In any case, if you choose to use it, don't forget to set the css of the link (hover and active) to `text-decoration:none` to get rid of that stupid underline. This is necessary for some browsers (Firefox 11.0 for sure). – Yetti Apr 20 '12 at 15:18
  • 24
    But you're not supposed to nest buttons inside a elements, visa versa. At least it's not a valid way of doing it in HTML 5 – Patrick Magee Jun 11 '12 at 15:01
  • 1
    Yep, this doesn't work in even IE10, for the reasons Patrick explains. – Ciaran Gallagher Feb 13 '13 at 17:29
  • No nesting of buttons inside of action element. http://stackoverflow.com/questions/6393827/can-i-nest-a-button-element-inside-an-a-using-html5 – Papa Burgundy Sep 01 '13 at 16:38
25

Using bootstrap this is the shortest and cleanest approach to create a link to a controller action that appears as a dynamic button:

<a href='@Url.Action("Action", "Controller")' class="btn btn-primary">Click Me</a>

Or to use Html helpers:

@Html.ActionLink("Click Me", "Action", "Controller", null, new { @class = "btn btn-primary" })
Community
  • 1
  • 1
Cameron Forward
  • 702
  • 8
  • 16
16

if you don't want to use a link, use button. you can add image to button as well:

<button type="button" onclick="location.href='@Url.Action("Create", "Company")'" >
   Create New
   <img alt="New" title="New" src="~/Images/Button/plus.png">
</button>

type="button" performs your action instead of submitting form.

Amir Chatrbahr
  • 2,260
  • 21
  • 31
15

A late answer but this is how I make my ActionLink into a button. We're using Bootstrap in our project as it makes it convenient. Never mind the @T since its only an translator we're using.

@Html.Actionlink("Some_button_text", "ActionMethod", "Controller", "Optional parameter", "html_code_you_want_to_apply_to_the_actionlink");

The above gives a link like this and it looks as the picture below:

localhost:XXXXX/Firms/AddAffiliation/F0500

picture demonstrating button with bootstrap

In my view:

@using (Html.BeginForm())
{
<div class="section-header">
    <div class="title">
        @T("Admin.Users.Users")
    </div>
    <div class="addAffiliation">
        <p />
        @Html.ActionLink("" + @T("Admin.Users.AddAffiliation"), "AddAffiliation", "Firms", new { id = (string)@WorkContext.CurrentFirm.ExternalId }, new { @class="btn btn-primary" })
    </div>
</div>

}

Hope this helps somebody

Joachim Rohde
  • 5,915
  • 2
  • 29
  • 46
Emperor 2052
  • 517
  • 1
  • 5
  • 14
  • 1
    Works cool! nice and simple, the htmlAttribute `new { @class="btn btn-primary" })` +one – Irf Mar 01 '16 at 10:28
15

Just simply :

<button onclick="@Url.Action("index", "Family", new {familyid = Model.FamilyID })">Cancel</button>
Patrick Kan
  • 159
  • 1
  • 2
  • this still invokes the post method of the view for me, any idea why? – DevDave Sep 20 '12 at 13:15
  • This isn't valid syntax. IE10 throws a JavaScript critical error with this line, "SCRIPT5017: Syntax error in regular expression". – Ciaran Gallagher Feb 13 '13 at 17:34
  • 1
    Good answer, but without surrounding the `onclick` contents with `location.href` (so `onclick="location.href='@Url.Action(....)'"`) I couldn't get it to work. – SharpC Oct 21 '15 at 09:38
12

A simple way to do make your Html.ActionLink into a button (as long as you have BootStrap plugged in - which you probably have) is like this:

@Html.ActionLink("Button text", "ActionName", "ControllerName", new { @class = "btn btn-primary" })
haugan
  • 385
  • 4
  • 12
12

You can't do this with Html.ActionLink. You should use Url.RouteUrl and use the URL to construct the element you want.

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • Hi, sorry I am very new to MVC. How would I use the Url.RouteURL to achieve the image? – uriDium Mar 09 '10 at 19:58
  • What I meant is you can't generate a nested img tag (or button tag) with a simple call to ActionLink. Of course, CSS styling the a tag itself is a way to get around it, but nonetheless you can't get an img tag. – Mehrdad Afshari Feb 04 '11 at 16:27
9

<button onclick="location.href='@Url.Action("NewCustomer", "Customers")'">Checkout >></button>

  • This worked for me on IE10. This is a good solution if you simply want to use a button rather than an image, although having to use using inline JavaScript for a simple link is probably not ideal. – Ciaran Gallagher Feb 13 '13 at 17:37
  • 1
    (and just to be sure, I tested it on Opera, Safari, Chrome and Firefox and it worked) – Ciaran Gallagher Feb 13 '13 at 17:44
8

Even later response, but I just ran into a similar issue and ended up writing my own Image link HtmlHelper extension.

You can find an implementation of it on my blog in the link above.

Just added in case someone is hunting down an implementation.

Mirko
  • 4,284
  • 1
  • 22
  • 19
5
<li><a href="@Url.Action(  "View", "Controller" )"><i class='fa fa-user'></i><span>Users View</span></a></li>

To display an icon with the link

Andrew Day
  • 563
  • 10
  • 23
4

Do what Mehrdad says - or use the url helper from an HtmlHelper extension method like Stephen Walther describes here and make your own extension method which can be used to render all of your links.

Then it will be easy to render all links as buttons/anchors or whichever you prefer - and, most importantly, you can change your mind later when you find out that you actually prefer some other way of making your links.

mookid8000
  • 18,258
  • 2
  • 39
  • 63
3

you can create your own extension method
take look at my implementation

public static class HtmlHelperExtensions
{
    public static MvcHtmlString ActionImage(this HtmlHelper html, string action, object routeValues, string imagePath, string alt, object htmlAttributesForAnchor, object htmlAttributesForImage)
    {
        var url = new UrlHelper(html.ViewContext.RequestContext);

        // build the <img> tag
        var imgBuilder = new TagBuilder("img");
        imgBuilder.MergeAttribute("src", url.Content(imagePath));
        imgBuilder.MergeAttribute("alt", alt);
        imgBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributesForImage));
        string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);

        // build the <a> tag
        var anchorBuilder = new TagBuilder("a");
        anchorBuilder.MergeAttribute("href", action != null ? url.Action(action, routeValues) : "#");
        anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
        anchorBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributesForAnchor));

        string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);
        return MvcHtmlString.Create(anchorHtml);
    }
}

then use it in your view take look at my call

 @Html.ActionImage(null, null, "../../Content/img/Button-Delete-icon.png", Resource_en.Delete,
               new{//htmlAttributesForAnchor
                   href = "#",
                   data_toggle = "modal",
                   data_target = "#confirm-delete",
                   data_id = user.ID,
                   data_name = user.Name,
                   data_usertype = user.UserTypeID
               }, new{ style = "margin-top: 24px"}//htmlAttributesForImage
                    )
Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92
2

For Material Design Lite and MVC:

<a class="mdl-navigation__link" href='@Url.Action("MyAction", "MyController")'>Link Name</a>
Rody Davis
  • 1,825
  • 13
  • 20
1

There seems to be lots of solutions on how to created a link that displays as an image, but none that make it appear to be a button.

There is only good way that I have found to do this. Its a little bit hacky, but it works.

What you have to do is create a button and a separate action link. Make the action link invisible using css. When you click on the button, it can fire the click event of the action link.

<input type="button" value="Search" onclick="Search()" />
 @Ajax.ActionLink("Search", "ActionName", null, new AjaxOptions {}, new { id = "SearchLink", style="display:none;" })

function Search(){
    $("#SearchLink").click();
 }

It may be a pain in the butt to do this every time you add a link that needs to look like a button, but it does accomplish the desired result.

bsayegh
  • 990
  • 6
  • 17
1

use FORMACTION

<input type="submit" value="Delete" formaction="@Url.Action("Delete", new { id = Model.Id })" />
Serge
  • 343
  • 5
  • 8
1
@using (Html.BeginForm("DeleteMember", "Member", new { id = Model.MemberID }))
    {
        <input type="submit" value="Delete Member" onclick = "return confirm('Are you sure you want to delete the member?');" />
    }
Mark Hall
  • 53,938
  • 9
  • 94
  • 111
user477864
  • 31
  • 2
0

The way I have done it is to have the actionLink and the image seperately. Set the actionlink image as hidden and then added a jQuery trigger call. This is more of a workaround.

'<%= Html.ActionLink("Button Name", "Index", null, new { @class="yourclassname" }) %>'
<img id="yourImage" src="myImage.jpg" />

Trigger example:

$("#yourImage").click(function () {
  $('.yourclassname').trigger('click');
});
hatsrumandcode
  • 1,871
  • 2
  • 19
  • 21
0

This is how I did it without scripting:

@using (Html.BeginForm("Action", "Controller", FormMethod.Get))
{
    <button type="submit" 
            class="btn btn-default" 
            title="Action description">Button Label</button>
}

Same, but with parameter and confirmation dialog:

@using (Html.BeginForm("Action", "Controller", 
        new { paramName = paramValue }, 
        FormMethod.Get, 
        new { onsubmit = "return confirm('Are you sure?');" }))
{
    <button type="submit" 
            class="btn btn-default" 
            title="Action description">Button Label</button>
}
J-M
  • 1,207
  • 11
  • 18
0

Url.Action() will get you the bare URL for most overloads of Html.ActionLink, but I think that the URL-from-lambda functionality is only available through Html.ActionLink so far. Hopefully they'll add a similar overload to Url.Action at some point.

Bishan
  • 15,211
  • 52
  • 164
  • 258
Dhanasekar
  • 49
  • 1
  • 2
0

Just found this extension to do it - simple and effective.

Shaul Behr
  • 36,951
  • 69
  • 249
  • 387