MVC 4: Custom Routes

2019-07-26 05:12发布

I see a lot of problems with MVC routes and I'm having a similar problem getting a route to match a URL.

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

routes.MapRoute("Beer", "Beer/{beerid}", new { controller = "Beer", action = "Id", beerid = 0});

routes.MapRoute("Beer", "Beer/{beername}", new { controller = "Beer", action = "Name" });

BeerController Methods

public ActionResult Id(int beerid)
public ActionResult Name(string beername)

If I change the methods to the following,

public ActionResult Id(int? id)    
public ActionResult Name(string id)

the default routing works with the following URLs:

http://localhost/Beer/Id/100
http://localhost/Beer/Name/Coors

But what I'm going for is just

http://localhost/Beer/100
http://localhost/Beer/Coors

Any ideas?

1条回答
小情绪 Triste *
2楼-- · 2019-07-26 05:52

So a couple things here.

  1. More specific routes should be placed before more general routes, because the first route that is matched will be used and routes are inspected in the order they are added.

  2. If you plan on not providing the name of the action in your URL then you will need to do something to ensure the correct route is targeted so the correct default value will be used. In your case you could use a route constraint to distinguish between the two. Try changing your beer id route to this:

    routes.MapRoute(
        name: "Beer",
        url: "Beer/{beerid}",
        defaults: new { controller = "Beer", action = "Id", beerid = 0},
        constraints: new { beerid = @"\d+" }
    );
    

    The constraint will ensure that the route only matches two-segment URLs where the second segment is composed of one or more digits. This route as well as your route for beer name should be placed before the default route.

UPDATE

My configuration seems to be yielding the results you want. The entirety of my RegisterRoutes method is as follows:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
    name: "Id",
    url: "Beer/{beerid}",
    defaults: new { controller = "Beer", action = "Id", beerid = 0 },
    constraints: new { beerid = @"\d+" }
);

routes.MapRoute(
    name: "Name",
    url: "Beer/{beername}",
    defaults: new { controller = "Beer", action = "Name" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
查看更多
登录 后发表回答