简体   繁体   中英

ASP.NET MVC MapRoute more than 1 parameter issue

I'm trying to use MapRoute with more than one parameter, but it is not working properly.

My RegisterRoutes :

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

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    routes.MapRoute(
        "TestRoute",                                              // Route name
        "{controller}/{action}/{id}/{tID}",                           // URL with parameters
        new { controller = "Test", action = "Index", id = "", tID = "" }  // Parameter defaults
    );
}

My Test controller:

public class TestController : Controller
{
    public ActionResult Index(int? id, int? tID)
    {
        // Some code to create viewModel

        return View(viewModel);
    }
}

I call this method from a Html.ActionLink :

@Html.ActionLink(@item.Description, "Index", "Test", 
    new { id = @item.CatID, tID = @item.myTID }, null)

However, it returns the url as: /Test/Index/3?tID=264981 instead of /Test/Index/3/264981

Does anybody know what I'm doing wrong?

There are several issues here:

  1. More specific routes should be registered first before general ones.
  2. Since the first match always wins, routes need to be constrained in some way. For example, to keep route A that is registered before route B from matching the cases that should be handled by route B.
  3. The most logical behavior is usually to make route values required , not optional.


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

    // Register the most specific route first
    routes.MapRoute(
        "TestRoute",

        // Constrain the URL - the simplest way is just to add a literal
        // segment like this, but you could make a route constraint instead.
        "Test/{action}/{id}/{tID}", 

        // Don't set a value for id or tID to make these route values required.
        // If it makes sense to use /Test/Action without any additional segments,
        // then setting defaults is okay.
        new { controller = "Test", action = "Index" }  
    );

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

Reference: Why map special routes first before common routes in asp.net mvc?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM