views:

120

answers:

2

Hi everyone,

I have a route defined with several hardcoded (non-parameter) segments:

routes.MapRoute(null, "suggestion/list/by/{tag}", 
       new { controller = "Suggestion", action = "List", tag = UrlParameter.Optional });

Suppose I'm in the Index view of SuggestionController, which has a Suggestion object for Model, how can I create a link that matches that route?

I know I can accomplish I by using plain ol' html like:

<a href="/suggestion/list/by/<%=Model.Tag %>"><%=Model.Tag %></a>

But this makes it impossible to pass on other route parameters (as a RouteValueDictionary, for instance), doesn't it?

I was actually wondering whether is would be possible to do using one of the provided helpers, but without naming the route. I'd prefer to keep the route name as null in order to avoid hard-coding to much on my views, but I can't figure out how to user these non-parameter segments in Html.ActionLink or RouteLink methods.

Any ideas?

Thanks in advance.

+1  A: 

The helper methods will take into account routes that you set up so you will be able to use them and they will output the URLs as you want. For example:

<%= Html.Action(Model.Tag, "List", "Suggestion", new { tag = Model.Tag }, null) %>

Or even better, if you are using the MVC futures assembly you will be able to do away with the magic strings and do:

<%= Html.Action<SuggestionController>(c => c.List(Model.Tag), Model.Tag) %> // Add checks for null if Tag can be null

EDIT: As Pointed out in the comments, there is a typo above, the calls to Action, should be ActionLink

s1mm0t
Thanks for our answer s1mm0t. 2 things: I imagine you meant Html.ActionLink on the first code snippet (Html.Action has no such overload), so I tried ActionLink like you suggested but it renders the following route: /suggestion/list/by?tag=TestTagwhich of course, doesn't work. I needed it actually to render: /suggestion/list/by/TestTagAm I missiing something in the route definition?
Sergi Papaseit
Yes you are right, there is a typo in the solution above which I've now added an edit about. I have tested this twice now and it works fine for me with both solutions above (using ActionLink obviously ;O)). Is your route definitely being used? The more specific routes should be added first otherwise a more general one will be used. Try adding your route above as the first route, just as a test and then try using ActionLink.
s1mm0t
Ok this is embarrassing... I had a typo in my route definition for the *only parameter* in it. My route was defined as suggestion/list/by/{it}, which of course will render tap as a query string parameter. :þ Thanks s1mm0t, you're going home with the right answer ;)
Sergi Papaseit
+1  A: 

I believe that it is best to use RouteLink method in this case. Using RouteLink you can explicitly define the name of the route you want to use. So if you dont have any other reason not to put a name in the route, name it like "suggestion" (or anything else you want). So the RouteLink will be:

<%: Html.RouteLink(Model.Tag, "suggestion", new RouteValueDictionary { tag = Model.Tag })

I had a similar problem with a complex route, and this was the only solution i have found. Hope it helps...

goldenelf2
Tanks. I was aware this would work, but I was curious as to whether it would be possible without tight-coupling my views to my route definitions. It surely must be possible?
Sergi Papaseit