Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 584
iggyweb Avatar asked May 19 '14 12:05

iggyweb


2 Answers

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.

like image 107
Lanorkin Avatar answered Oct 20 '22 05:10

Lanorkin


The Mapping takes the first matching rule. The "Item"-Route would never be used because the Article-Root will catch all request that could match "Item"-Route. Check the order of the routes AND delete the {} surrounding news.

routes.MapRoute(
            name: "Item",
            url: "News/Item/{id}/{itemName}",
            defaults: new { controller = "News", action = "Item" }
        );
like image 33
Tobias Avatar answered Oct 20 '22 04:10

Tobias