asp.net mvc Html.ActionLink() keeping route value I don't want
Asked Answered
O

9

46

I have the following ActionLink in my view

<%= Html.ActionLink("LinkText", "Action", "Controller"); %>

and it creates the following URL http://mywebsite.com/Controller/Action

Say I add an ID at the end like so: http://mywebsite.com/Controller/Action/53 and navigate to the page. On this page I have the markup I specified above. Now when I look at the URL it creates it looks like this:

http://mywebsite.com/Controller/Action/53 (notice the addition of the ID)

But I want it to remove the ID and look like it did originally, like this http://mywebsite.com/Controller/Action (notice no ID here)

Any ideas how I can fix this? I don't want to use hard coded URLs since my controller/actions may change.

Ornis answered 23/4, 2009 at 7:21 Comment(1)
See this workitem for Microsoft's official explanation of this issue and workarounds.Damper
O
48

The solution is to specify my own route values (the fourth parameter below)

<%= Html.ActionLink("LinkText", "Action", "Controller", 
    new { id=string.Empty }, null) %>
Ornis answered 23/4, 2009 at 21:17 Comment(4)
Thanks for this answer, I needed it for another circumstance but you hit the nail right on the head with that trailing null!Ranique
This seems a little kludgey... I need to do the same thing but I think I might have to create a new extension method like Arnis L posted belowCd
Also this seems like the functionality should be built-in to the framework since this situation comes up often. For example, having a menu, you don't want the menu link to contain all of the parameters, just the actionCd
i m using .NET 4 and mvc2 but string.empty does not solve the above mentioned problem and actionlink still keeping the ambient valuesKalynkam
B
13

It sounds like you need to register a second "Action Only" route and use Html.RouteLink(). First register a route like this in you application start up:

routes.MapRoute("ActionOnly", "{controller}/{action}", 
   new { controller = "Home", action = "Index" } );

Then instead of ActionLink to create those links use:

Html.RouteLink("About","ActionOnly")
Broadfaced answered 28/4, 2010 at 14:57 Comment(1)
+1 for using Html.RouteLink(). Worked for me - you can also specify routeValues so MVC loses the current action and goes back to the index or something, eg. @Html.RouteLink("Cancel", "ThisSection_default", new { action = "Index" }).Wortham
B
10

The problem is the built in methods take input from the URL you are currently on as well as what you supply. You could try this:

<%= Html.ActionLink("LinkText", "Action", "Controller", new { id = ""}) %>

That should manually wipe the id parameter.

Breastfeed answered 23/4, 2009 at 8:38 Comment(0)
M
4

Don't know why, but it didn't work for me (maybe because of Mvc2 RC). Created urlhelper method =>

 public static string
            WithoutRouteValues(this UrlHelper helper, ActionResult action,params string[] routeValues)
        {
            var rv = helper.RequestContext.RouteData.Values;
            var ignoredValues = rv.Where(x=>routeValues.Any(z => z == x.Key)).ToList();
            foreach (var ignoredValue in ignoredValues)
                rv.Remove(ignoredValue.Key);
            var res = helper.Action(action);
            foreach (var ignoredValue in ignoredValues)
                rv.Add(ignoredValue.Key, ignoredValue.Value);
            return res;
        }
Magocsi answered 21/1, 2010 at 13:3 Comment(2)
I had the same problem (using MVC2 RTM). I had route value called plan and the last (default) route added it as ?plan=X. So I added default value to the last (default) route for my plan route value as plan = string.Empty. Even though route definition doesn't define URL segment variable called plan. As long as it worked, I'm fine with it.Dotti
I used a variation of this to reliably and elegantly resolve this issue.Venegas
C
4

If you either don't know what values need to be explicitly overridden or you just want to avoid the extra list of parameters you can use an extension method like the below.

<a href="@Url.Isolate(u => u.Action("View", "Person"))">View</a>

The implementation details are in this blog post

Casque answered 21/8, 2013 at 17:21 Comment(2)
Clean and simple, very nice +1Beefwood
It's a dirty hack... but it's still the best solution I found so far.Republic
C
4

I explicitly set the action name as "Action/". Seems a little like a hack but it's a quick fix.

@Html.ActionLink("Link Name", "Action/", "Controller")
Cia answered 30/7, 2014 at 14:6 Comment(1)
I had to do this as well, the link was to index, so I was able to use just "/" as the action. @Html.ActionLink("Link Name", "/", "Controller")Hedges
M
3

Another way is to use ActionLink(HtmlHelper, String, String, RouteValueDictionary) overload, then there are no need to put null in the last parameter

<%= Html.ActionLink("Details", "Details", "Product", new RouteValueDictionary(new { id=item.ID })) %>
Milker answered 26/8, 2010 at 13:25 Comment(0)
M
1

The overloads of Html.ActionLink are changed on the later versions of MVC. On MVC 5 and above. This is how to do this:

@Html.ActionLink("LinkText", "Action", "Controller", new { id = "" }, null)

Note I passed "" for id parameter and null for HTMLATTRIBUTES.

Mamiemamma answered 14/8, 2017 at 19:3 Comment(0)
T
0

I needed my menu links to be dynamic. Rather than implement a lot of extra code and routing for every single page I simple dispensed with the HTML helper.

<a href="@(item.websiteBaseURL)/@(item.controller)/@(item.ViewName)">@item.MenuItemName</a>
Tankoos answered 27/1, 2014 at 22:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.