views:

296

answers:

3

Hi,

I've got the following route:

routes.MapRoute(
"Search",
"Search.aspx/l-{lID}/t-{tID}/p-{pID}/s-{sID}",
new { 
    controller = "Search", 
    action = "Search", 
    lID = "",
    tID = "", 
    pID = "", 
    sID = "" },
new { lID = @"\d{0,}", 
    tID = @"\d{0,}", 
    pID = @"\d{0,}", 
    sID = @"\d{0,}" }
);

Which works fine providing my url is http://localhost:1234/Search.aspx/l-1/t-1/p-1/s-1 but I want some of these parameters to be empty so a url may look like: http://localhost:1234/Search.aspx/l-/t-/p-1/s- however when this happens I keep getting 404 errors.

Does anyone know how I can make this route work so I can have empty values?

Update:

Following the advice I upgraded the project to MVC 2 however the problem still occurs. My route now looks like:

routes.MapRoute(
"Search",
"Search.aspx/l-{lID}/t-{tID}/p-{pID}/s-{sID}",
new
{
   controller = "Search",
   action = "Search",
   lID = UrlParameter.Optional,
   tID = UrlParameter.Optional,
   pID = UrlParameter.Optional,
   sID = UrlParameter.Optional
},
new
{
   lID = @"\d{0,}",
   tID = @"\d{0,}",
   pID = @"\d{0,}",
   sID = @"\d{0,}" }
);

I'm still getting 404's when trying to view the view with empty values in.

Also another issue that has come up since moving to version 2 is that the RedirectToRoute can't seem to find the route. I get

No route in the route table matches the supplied values.

error message. My code looks like:

return RedirectToRoute( 
"Search", 
new { 
    lID = lID, 
    tID = tID,
    pID = pID,
    sID = sID 
    } 
);

Again any help would be much appreciated.

Thanks

A: 

Optional URL Parameters are available as part of MVC2 - Check out Phil Haack's post explaining it. This was added in MVC 2 RC 2.

Something else to note, MVC2 will not require .Net 4, it will run on 3.5 as well. This means if you can wait a bit, you can go to MVC2 without doing the full 4.0 upgrade and get this functionality.

Nick Craver
Sorry I should have stated this is mvc version 1
Simon G
@Simon - To clarify, there isn't a good way to do this in MVC 1, but MVC 2 is around the corner and should be a fairly quick/painless upgrade to get what you're after
Nick Craver
I've upgraded to version 2 and the same problem still exists. Any more thoughts? Thanks
Simon G
@Simon - What are the types on your 4 parameters, ints or strings?
Nick Craver
ints, in the Action there specified as nullable ints - int?
Simon G
@Simon - I wonder if MVC 2 isn't removing it from the dictionary since it's explicit, what happens when you remove the `new { lID = @"\d{0,}", tID = @"\d{0,}", pID = @"\d{0,}", sID = @"\d{0,}" }` parameter?
Nick Craver
A: 

A little long winded, but it should do the trick.

//All params.
routes.MapRoute(
  "Search",
  "Search.aspx/l-{lID}/t-{tID}/p-{pID}/s-{sID}",
  new { 
    controller = "Search", 
    action = "Search", 
    lID = "",
    tID = "", 
    pID = "", 
    sID = ""
  },
  new {
    lID = @"\d{0,}", 
    tID = @"\d{0,}", 
    pID = @"\d{0,}", 
    sID = @"\d{0,}"
  }
);

//First three params
routes.MapRoute(
  "Search",
  "Search.aspx/l-{lID}/t-{tID}/p-{pID}",
  new { 
    controller = "Search", 
    action = "Search", 
    lID = "",
    tID = "", 
    pID = "", 
  },
  new {
    lID = @"\d{0,}", 
    tID = @"\d{0,}", 
    pID = @"\d{0,}", 
  }
);

//First two params
routes.MapRoute(
  "Search",
  "Search.aspx/l-{lID}/t-{tID}",
  new { 
    controller = "Search", 
    action = "Search", 
    lID = "",
    tID = "", 
  },
  new {
    lID = @"\d{0,}", 
    tID = @"\d{0,}", 
  }
);

//First param
routes.MapRoute(
  "Search",
  "Search.aspx/l-{lID}",
  new { 
    controller = "Search", 
    action = "Search", 
    lID = "",
  },
  new {
    lID = @"\d{0,}", 
  }
);

//No params.
routes.MapRoute(
  "Search",
  "Search.aspx",
  new { 
    controller = "Search", 
    action = "Search", 
  }
);

I should note that it'll probably have to be in the is order given that ASP.NET MVC is lazy about routes, and will come to the first route it finds that matches. That said, you should probably look at setting the constraints on the ids to @"\d{1,}", as they'll likely hit that one all the time...

Dan Atkinson
A: 

After looking at both UrlParameter.Optional and create an action filter as described here I still couldn't get either working with null values.

In the end I pass zero to the action and check if its zero then make the value null. Not an idea situation but it works and will do until I find something better.

Simon G