Search code examples
asp.net-mvc-4asp.net-mvc-routing

ASP.Net Routing: Customer ID not passing to action


see my url localhost:55831/Customers/Edit/1/ALFKI which i generate using @Html.RouteLink

@Html.RouteLink("Edit", "PageWithId",
new
{
    controller = "Customers",
    action = "Edit",
    id = item.CustomerID,
    page = ViewBag.CurrentPage
})

here is my routing code for PageWithId i tried two routing one after one but none work

    routes.MapRoute(
        name: "PageWithId",
        url: "{controller}/{action}/{page}/{id}"
    );

AND

routes.MapRoute(
    name: "CustomerEditWithId",
    url: "Customers/Edit/{page}/{id}",
    defaults: new { controller = "Customers", action = "Edit" }
);

my all routing code

routes.MapRoute(
name: "PageWithSort",
url: "{controller}/{action}/{page}/{SortColumn}/{CurrentSort}",
defaults: new { action = "Index", page = UrlParameter.Optional, SortColumn = UrlParameter.Optional, CurrentSort = UrlParameter.Optional }
);

routes.MapRoute(
name: "PageWithId",
url: "{controller}/{action}/{page}/{id}"
);


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

please some one help because when i am clicking ob this link localhost:55831/Customers/Edit/1/ALFKI then customer id ALFKI is not passing to edit action. i debug the edit action code and found id is getting null always. i tried few routing for edit action but no luck still.


Solution

  • The order of routes matters. Routes are checked in order and the first matching route wins.

    Because your first (PageWithSort) route matches any route with between 1 and 5 segments, then /Customers/Edit/1/ALFKI, which contains 4 segments matches, and no further routes are checked. And since ALFKI is being passed to the 4th segment named SortColumn, then it will only be bound to a parameter named SortColumn in your Edit() method (not to something named id)

    As it stands, your PageWithId and Default routes are pointless since they can never be hit.

    In additional, only the last parameter in a route definition can be marked with UrlParameter.Optional.

    You need to create specific routes, and locate them in the correct order. Change your route definitions to (note I have omitted the PageWithSort route because its not clear what you want to do with that and it contains errors anyway)

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

    Now any url that begins with /Customers/Edit and contains 2 additional segments will match the CustomerEditWithId route, and the 3rd segment will be bound to a parameter named page and the 4th segment will be bound to a parameter named id. Therefore your method in CustomersController should be

    public ActionResult Edit(int page, string id)