2

I've a small issue with URL generation & routing under ASP.NET MVC 2. My route has optional parameters and the URL is correctly generated if the parameters are specified.

Thus:

routes.MapRoute("Blog", "Articles/{tag}/{page}", new { controller = "Blog", action = "Index" });

with:

<%: Html.ActionLink(item.Tag, "Index", "Blog", new { tag = item.Tag }, null) %>

does correctly generates ~/Articles/item_tag/1. The link works, my view is rendered.

I have others link like:

<%: Html.ActionLink("See more articles", "Index", "Blog") %>

that generates ~/Blog instead of ~/Articles.

If I add a second route like:

routes.MapRoute("Blog2", "Articles", new { controller = "Blog", action = "Index" });

my URL is correctly rendered. I can't understand why I'd need to add this second route as it seems very redundant because the first route has optional segments.

Any help appreciated.

Fabian

EDIT: added routes code.

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

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

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

// News
routes.MapRoute("NewsDetails", "News/Details/{id}", new { controller = "News", action = "Details" });
routes.MapRoute("News", "News", new { controller = "News", action = "Index" });

// Articles
routes.MapRoute("BlogDetails", "Articles/Details/{id}", new { controller = "Blog", action = "Details" });
routes.MapRoute("BlogWithTag", "Articles/{tag}/{page}", new { controller = "Blog", action = "Index", tag = "", page = 1 });
routes.MapRoute("Blog", "Articles/{page}", new { controller = "Blog", action = "Index", page = 1 });

// Contact
routes.MapRoute("Contact", "Contact", new { controller = "Contact", action = "Create" });

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

2 Answers 2

1

Non-optional parameters are mandatory

As their name implies, they are nonoptional. So if you don't provide tag and page in your ActionLink() call, route won't hit this route definition.

So your example when you call Html.ActionLink() and provide tag parameter but not page I guess you must have a different route definition that starts with Article/... as well, because your route that you've provided here, is unable to generate your link:

/Articles/item_tag/1

Route doesn't have any knowledge of parameter types. This means that parameter page value was provided by other means either by:

  • existing page route data values
  • a different route definition

So what's in it for you?

What's important in your case is that not providing tag and page parameter values when generating links, your route definition won't get hit and your link will be incorrect.

Why did you actually get /Blog link? Simply because you probably still have the default route definition at the end:

{controller}/{action}/{id}

And since you did say that controller is Blog and action is Index but haven't provided Id, so it will use its default, this will generate your default link URL which is exactly /blog. It's quite obvious when you look at it this way isn't it?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I thought that having my controller method with optional parameters would suffice. I've modified my Global.asax.cs file like this: routes.MapRoute("Blog", "Articles/{tag}/{page}", new { controller = "Blog", action = "Index", tag = "", page = 1 }); But it still doesn't generates the right URL.
@Fabian Vilers: If you provide your complete route definition from Global.ascx.cs (add it to your question and format it), we will be able to help. Why? Simply because it should work with one route that defines defaults for tag and page. There's no need for second route definition whatsoever if those two parameters have defaults.
0

In this:

routes.MapRoute("Blog", "Articles/{tag}/{page}", new { controller = "Blog", action = "Index" });

The {tag} and {page} tokens are not optional. They are hard-coded into the URI and you have no default for them.

Because of the / between {tag} and {page} in your route, this will never generate a URI like ~/Blog.

3 Comments

It will if there's another route definition that starts with "Blog/..."
So your suggestion is to keep my "Blog2" route?
Yes, probably. Hard to be certain without working out a full routing strategy. You should do that, incidentally.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.