MVC 3 routing help with dynamic route

2019-08-09 04:06发布

问题:

Im trying to do something like this:

routes.MapRoute("Product", "{product}/{id}",
                            new
                                {
                                    action = "Product",
                                    controller = "Home",
                                    product = UrlParameter.Optional,
                                    id = UrlParameter.Optional
                                });

It gives me error when im trying to load page 404 i think, Im trying to make the url look like this: www.tables.com/productName/ID . How can i do it without adding a strong type word like this:

routes.MapRoute("Product", "Products/{product}/{id}", ... )

rest of the routes:

 routes.MapRoute("Product", "{product}/{id}",
                            new
                                {
                                    action = "Product",
                                    controller = "Home",
                                    product = UrlParameter.Optional,
                                    id = UrlParameter.Optional
                                });

            routes.MapRoute("Category", "Category/{category}/{template}",
                            new
                            {
                                action = "Index",
                                controller = "Category",
                                category = UrlParameter.Optional,
                                template = UrlParameter.Optional
                            });

            routes.MapRoute("Profile", "Profile/{fullName}",
                           new
                           {
                               action = "Index",
                               controller = "Profile",
                               fullName = UrlParameter.Optional
                           });


            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
            );

thanks.

回答1:

Your problem is that the Product route will match everything not starting with Category or Profile.

I would place the product route just before the default route and use a IRouteConstraint such that it doesn't match non products.

Code sample:

routes.MapRoute("Category", "Category/{category}/{template}",
                new
                {
                    action = "Index",
                    controller = "Category",
                    category = UrlParameter.Optional,
                    template = UrlParameter.Optional
                });

routes.MapRoute("Profile", "Profile/{fullName}",
               new
               {
                   action = "Index",
                   controller = "Profile",
                   fullName = UrlParameter.Optional
               });


routes.MapRoute("Product", "{product}/{id}",
                new
                    {
                        action = "Product",
                        controller = "Home",
                        product = UrlParameter.Optional,
                        id = UrlParameter.Optional
                    },
                new { product = new ProductRouteConstraint() });

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
);

And the route constraint:

public class ProductRouteConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            if (routeDirection == RouteDirection.IncomingRequest &&
                parameterName.ToLowerInvariant() == "product")
            {
                var productName = values[parameterName] as string;
                if (productName == null) 
                    return false;

                var productId = values["id"] as string;
                if (productId == null)
                    returns false;

                return ProductCatalogue.HasProductById(productId);
            }

            return false;
        }
    }

The ProductCatalogue should obviously be replaced with however you lookup products in your system.