Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Url.Action does not give the expected result. Unwanted route values remain

I have a MVC3 app with several routes. Two of them are defined like this:

routes.MapRoute(
  null,
  "System/{name}", // URL with parameters
  new { controller = "Systems", action = "Index" } // Parameter defaults
);
routes.MapRoute(
  null,
  "Carrier/{name}", // URL with parameters
  new { controller = "Carriers", action = "Index" } // Parameter defaults
);

Now, in my menu I have two links to these routes that are created using Url.Action:

Url.Action("Index","Systems")
Url.Action("Index","Carriers")

Now when i start the application, everything seems fine, and the links in the menu show as /System/ and /Carrier/, and that is the expected value.

However, when i browse to for example /System/MySystem in the web page i would still want the links to point to the same place, but now they point to /System/MySystem and /Carrier/MySystem.

I have tried lots of things to keep the link from using the name from the route value, but to no avail. The strangest case i experienced was when i tried this:

Url.Action("Index","Systems", new{name = (string)null})

Now the link showed up as

/System?name=MySystem

Are there any good way here to make sure that the name value from the route values does not interfer with these links in any way?

like image 752
Øyvind Bråthen Avatar asked Sep 07 '12 12:09

Øyvind Bråthen


1 Answers

As you noticed the Url. helpers reuse the previously given route parameters.

As a workaround (I hope that there is a more elegant solution...) you can remove the name entry from the RouteData.Values in your view:

So before calling you Url.Action in your view:

Url.Action("Index","Systems")
Url.Action("Index","Carriers")

Remove the prefilled name from the RequestContext:

@{
     Request.RequestContext.RouteData.Values.Remove("name");
}

It's also an workaround but if you slightly modify your routes with providing a default null value for your name segment:

routes.MapRoute(
  null,
  "System/{name}", // URL with parameters
  new { controller = "Systems", action = "Index", name = (string)null }
);
routes.MapRoute(
  null,
  "Carrier/{name}", // URL with parameters
  new { controller = "Carriers", action = "Index", name = (string)null }
);

Your original solution ("nulling" the name in the Url.Action) will also work :

@Url.Action("Index", "Systems" , new {name = (string)null} )
like image 86
nemesv Avatar answered Dec 06 '22 06:12

nemesv