Search code examples
c#url-routingasp.net-mvc-5

MVC 5 Routing Issue - Mutiple Routes Incorrectly Targeting Same View


I have multiple routes configured, but for some reason, despite the rules addressing different Controllers and different Views, different links are routing to the same view. Please see below, I have included my RouteConfig file and example links below:

RouteConfig.cs

using System.Web.Mvc;
using System.Web.Routing;

namespace WebApplication1
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Account",
                url: "Account/{action}/{id}",
                defaults: new { controller = "Account", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Member",
                url: "Member/{action}/{id}",
                defaults: new { controller = "Member", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Root",
                url: "{action}/{id}",
                defaults: new { controller = "Home", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                    name: "Details",
                    url: "{controller}/{action}/{u}",
                    defaults: new
                    {
                        controller = "Member",
                        action = "Details",
                        u = UrlParameter.Optional
                    }
            );

            routes.MapRoute(
                name: "Article",
                url: "{Home}/{Article}/{id}/{articleName}",
                defaults: new { controller = "Home", action = "Article" }
            );

            routes.MapRoute(
                name: "Item",
                url: "{News}/{Item}/{id}/{itemName}",
                defaults: new { controller = "News", action = "Item" }
            );
        }
    }
}

Links

http://localhost:11508/Home/Article/2/Participate
http://localhost:11508/News/Item/2/Second-Test

As so can see, the links and rules are most certainly unique but for some reason the Item rule is being ignored, it is simply passing Id 2 to the Home/Article view.


Solution

  • You shouldn't include controller / action names in brackets - just pass them as is, so that path can be matched. Your last two routes should look like this:

            routes.MapRoute(
                name: "Article",
                url: "Home/Article/{id}/{articleName}",
                defaults: new { controller = "Home", action = "Article" }
            );
    
            routes.MapRoute(
                name: "Item",
                url: "News/Item/{id}/{itemName}",
                defaults: new { controller = "News", action = "Item" }
            );
    

    Also, it is good to place such specific routes before any other routes, not after default routes.

    UPDATE

    Basically it should be separate question, but it is easier to just answer it here.

    From comment:

    how I can get http://localhost:11508/Member/Details?u=testuser to be routed to http://localhost:11508/Member/Details/testuser instead of a showing parameter.

    1. Create controller action which accepts this parameter, like this one:

      public ActionResult Details(string u, ...)
      {
          var model = new ...
          ...
          return View(model);
      }
      
    2. Register route, which accepts u parameter as URL part, like this one

          routes.MapRoute(
              name: "MyRoute",
              url: "Member/Details/{u}",
              defaults: new { controller = "Member", action = "Details", u = UrlParameter.Optional }
          );
      

      Here {u} actually declares parameter name, and how it should be used (parsed / rendered) inside URL.

    3. Render link to the URL like this one:

      <a href="@Url.Action("Details", "Member", new {u = "testuser"})">linktext</a>
      

    In all these steps, u is that name of parameter which you will use.