ActionLink doesn't work, but RouteUrl does

I have a route

// Sample URL: /Fixtures/Team/id routes.MapRoute( "Fixtures-by-TeamID", "Fixtures/Team/{teamId}", new { controller = "Fixtures", action = "GetByTeamID", }, new { teamId = @"\d{1,3}" } ); 

and I'm trying to use ActionLink in ASP.net MVC p5.

 <%= Html.ActionLink(g.HomeTeam.TeamName, "Team", new { teamId = g.HomeTeam.TeamID })%> 

However, it does not work and does not give me

 <a href="/Fixtures/Team?teamId=118">Team A</a> 

If I use Url.RouteUrl, I get the correct link.

 <a href="<%=Url.RouteUrl("Fixtures-by-TeamID", new { teamId = g.HomeTeam.TeamID })%>"><%=g.HomeTeam.TeamName%></a> <a href="/Fixtures/Team/118">Team A</a> 

Any help would be great? Will this change in ASP.net MVC beta?

thanks

Donald

+4
source share
4 answers

In my experience, the only temporary action routes really work correctly when you have a single default route. As soon as you start adding custom routes like yours above, the action routes will become ... I think "skillfully" is the right word. The matching system does not work exactly as you expected.

In this case, you said that the action was “Team”, but this route does not correspond to the action of “Team”, it corresponds only to “GetTeamByID”. So the routing system keeps going and ends up giving you a route based on the default route. The id command is clearly not part of your default route, so it ends as a request parameter attached to the end.

MVC Beta has already been submitted, and this behavior has not changed.

Also, you still don’t see that the named route is clearer? Personally, I know.

I even take it one step further and actually create route helpers for all my own routes, which might look like this in your current example:

 <a href="<%= Url.FixturesByTeam(g.HomeTeam.TeamID) %>"><%= g.HomeTeam.TeamName %></a> 

Or even:

 <%= Html.LinkToFixturesByTeam(g.HomeTeam) %> 

where you can derive values ​​for the name and identifier directly from the model.

+1
source

Try the following:

 // Sample URL: /Fixtures/Team/id routes.MapRoute( "Fixtures-by-TeamID", "Fixtures/Team/{teamId}", new { controller = "Fixtures", action = "Team", teamId = -1 } ); 

your controller should look like this:

 public class FixturesController : BaseController // or whatever { /*...*/ public ActionResult Team(int teamId) { return View("Detail", Team.GetTeamById(teamId)) // or whatever } /*...*/ } 

And your link will look like

 <%= Html.ActionLink("Click here for the team details", "Team", "Fixtures", new { teamId = ViewModel.Data.Id /*orwhateverlol*/ }) %> 

(I do not have MVC on this machine, so all of this from memory may have a syntax error or some arguments change).

Note that the route map route matches your 1) controller, 2) step 3) the name of the argument. I found the default action (the third argument in MapRoute) works, while I have never seen your overload of this method before (it may be a delay from the previous version).

Also observe how your FixturesController matches the path (Fixtures) and matches the name of the action (Team), and also matches the argument (teamId).

Finally, the last ActionLink argument should match your controller arguments in the name (teamId) and type.

Its a little too “magical” at the moment (there LOTS string comparisons are happening in the background!). I hope this improves over time. The old Expression style was much better. You essentially named the method you want to run with the values ​​you wanted to pass. I hope they bring this style of expression back into the frame. Haak?

+1
source

Have you tried this yet?

 Html.ActionLink<FixturesController>(c => c.GetByTeamID(g.HomeTeam.TeamID), "Team") 

Besides

You may need to add action = "GetByTeamID" to your restrictions.

+1
source

When a parameter ("action" in this case) is determined only by default, and not by the route URL, it must be an exact match (if you do not force it to go against a specific route, as is the case with RouteUrl).

To make everything work the same way as now, you can add another route to the list just below the specified route:

routes.MapRoute ("Lamps by TeamID1", "Lamps / teams / {TeamID}", new {controller = "Fixtures", action = "Team",}, new {teamId = @ "\ d {1,3 } "});

OR you can add an action parameter to the route URL,

OR you could use a named route, just like you.

0
source

All Articles