So a couple things here.
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.
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 }
);