I have a controller named Movie, with an action named ByYear, which takes the year as a parameter :
public ActionResult ByYear(int year)
{
ViewData["Title"] = string.Format("Movies released in {0}", year);
var repository = MvcApplication.GetRepository();
var movies = repository.Medias
.OfType<Movie>()
.Where(m => m.Year == year);
return View("Index", movies);
}
I’d like to access this action with the following URL : /Movie/ByYear/{year}, but the only valid route for this action is this : /Movie/ByYear?year={year}.
I tried to add new routes in my application’s RegisterRoutes method, but I can’t find a way to get the desired result…
Could anyone tell me how to achieve that ?
Note: this is actually very similar to this question, but no answer was accepted, and the highest voted answer makes no sense to me as I’m completely new to MVC…
Change the name of your parameter
yeartoidand this will match the default route that MVC adds to your project.So for further clarification, let’s take a look at the default route added by ASP.NET MVC:
In this route you can see three tokens that are named specifically for
controller,action, and the third token which is passed to the action isid. When a request comes into your application, ASP.NET MVC will analyze the routes that are currently mapped and try to find a method signature that matches them by using reflection against your controllers.When it looks at your
Moviecontroller, it sees an action calledByYear, however that method takes an integer calledyear, notid. This is why you end up with something like/Movie/ByYear?year={year}when you create anActionLinkfor that particular Action. So to fix this, you have two options:The first and most simple method to fix this is to just change the method signature for your Action to accept a parameter named
idwhich is what I recommended above. This will work fine, but I can see where it might cause a little bit of confusion when you go back to that source later and wonder why you called that parameterid.The second method is to add another route that matches that method signature. To do this, you should open your Global.asax and just add the following (untested, but should work):
This route is hard-coded, yes, but it won’t break the other routes in your system, and it will allow you to call the method parameter
year.EDIT 2: Another thing to note is that the routing engine will stop on the first route it finds that matches your request, so any custom routes like this should be added before the default route so you are sure they will be found.