1

I need the following routes:

example.com/products
goes to a product categories page (e.g. cars, trucks, buses, bikes)
controller=Products, action=Categories()

example.com/products?a=1&b=2
goes to an index of all products in a particular category (e.g. Ford, Honda, Chevy)
controller=Products, action=Index(string a, string b)

The routes only differ on the querystring, and it seems that MVC ignores anything after the "?". So of course only one rule will ever get hit--the first one.

How do I differentiate between the two?

Edit: stated differently, I want two routes. Is it possible to use the querystring in the route or does MVC truly ignore it? Is there any way to hack it, or use a custom routing scheme of some kind, much like I can do custom binding and custom validation?

mvcstudent
  • 37
  • 1
  • 5
  • With URLs like that you don't need to -- you can return the correct view if a & b are set or return index if it is not. Why not differentiate the URLs like so: `example.com/products` `example.com/products/a/b` In other words, why do you want `a` and `b` to be query parameters instead of being part of the URL? If you make them part of the URL, the routing is simple: put the complex route (requiring `a` and `b` first) and the less complex route second. – Cymen Sep 13 '11 at 01:35
  • thanks but that is not what we are doing, as you are encoding transient data in the route itself which is a resource; that's the purpose of the querystring which formats the data appropriately. As far as your first suggestion, yes, we could stick everything in one action method and decide in there what view to return--but then I'm doing my own routing which seems silly, I'd like the framework to do it for me. – mvcstudent Sep 13 '11 at 03:14
  • There are more discussions about this on stackoverflow. This might be appropriate: http://stackoverflow.com/questions/968904/asp-net-mvc-url-routing-vs-querystring – Cymen Sep 13 '11 at 16:50

1 Answers1

1

Introduce Parameters. ASP.NET MVC allows you to create 'pretty' URLs, and that's exactly what you should do here:

First, the route mappings:

routes.MapRoute(
    "SpecificProducts",
    "products/{a}/{b}",
    new { controller = "products", action = "Categories" }
    );

routes.MapRoute(
    "ProductsIndex",
    "products".
    new { controller = "products", action = "Index" }
    );

Then, the controller actions

public ActionResult Index()
{
}

public ActionResult Categories(string a, string b) //parameters must match route values
{
}

This will allow you to use a search-friendly URL and you don't have to worry about query string parameters.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • 1
    Thanks for the advice. Can we nonetheless do it with querystring parameters? That's the "proper" way to do it IMHO. The route should be oblivious of the formatting of the data. I've had similar problems many times, it seems that the MS routing guys didn't do a good design job here. – mvcstudent Sep 13 '11 at 03:16
  • @mvcstudent: it's not ms design at fail imo. Just handle the parameters that can be null in your action and all is ok. use only one route and set A and B to "optional parameters". – Iridio Sep 13 '11 at 05:34
  • But that still doesn't answer the question--is it possible to have two routes for the above scenario? Besides am using custom model binder so hacking it apart because of framework limitations is not ideal. – mvcstudent Sep 13 '11 at 10:41
  • 1
    @mvcstudent The answer is to not use a QueryString. You don't like that answer, but that is the answer. It's not a failing of MVC, and I disagree with your assertion that using querystring parameters is the 'proper' way to do anything. It isn't. (If it were, then it would be `The Way` instead of friendly URLs). Now, who am I supposed to say is in error? Microsoft, who has many senior programmers designing a framework? Or someone with 'mvcstudent' as their user name? – George Stocker Sep 13 '11 at 12:48
  • 1
    @George Stocker: cutesy name aside, we have formidably experience in web systems. Routes and URLs are resources that point to **content**. Querystrings are meant for **presentation**. When there are large numbers of filters, search criteria, paging refs, page size refs, etc., then the "pretty" approach breaks down fast. I'm sorry that you are offended if I don't like your answer. Whatever works for you I suppose. But I'd still like someone to tell me whether MVC routing can or cannot do what I need, as stated in the question? – mvcstudent Sep 13 '11 at 14:27
  • 1
    Routes are meant to delineate one resource from another, whereas as you stated, QueryString parameters are meant for Presentation logic*. Therefore you cannot expect a URL pointing to a resource to go to a different resource if the same URL is used, but with querystring parameters. This is not a failing of MVC, rather I don't believe you're using Querystrings correctly. – George Stocker Sep 13 '11 at 15:08
  • Good answer, caught me off guard for a moment. Though that isn't happening in my scenario (though perhaps my original question was not as clear as could be). Without QS I need to show a page without any filtering. With QS filtering is performed and narrows selections to smaller subsets of the original data. I believe QS do work in such a case. The base content is the same, the QS filters it. I think the source of contention is that I want to use different actions methods, but in our case, they simply render slightly different views. – mvcstudent Sep 13 '11 at 15:31
  • @mvcStudent if that's the case, then I'd call a "RenderAction" with the query string parameters (if they're present) and send in those Query String parameters to the renderaction as parameters. That way, you don't need to worry about the routes. – George Stocker Sep 13 '11 at 16:55