如何配置Route配置以获取类似localhost / Product(Controller)/ List(Action)/ Category(Id)的URL模式?

时间:2016-01-31 17:26:47

标签: c# asp.net-mvc

由于标题说明了我想要的东西,但具体到某种特定的,我希望有一个像localhost / Product / List / Category / Page这样的URL模式,但我无法找到解决方案。我确信它属于路由,因为它是MVC中的难题,我需要你的帮助来找到它的解决方案。

我的路线配置是:

 public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(null, "",
                new
                {
                    controller = "Home",
                    action = "Shop",

                });
            routes.MapRoute(null, "",
                new
                {
                    controller = "Product",
                    action = "list",
                    category = (string)null,
                    page = 1
                }
                );
            routes.MapRoute(null, "Page{page}",
            new
            {
                controller = "Product",
                action = "List",
                category = (string)null,
                subcategory = (string)null
            },
            new { page = @"\d+" }
            );

            routes.MapRoute(null,
            "{category}",
            new { controller = "Product", action = "List", page = 1 }
            );
            routes.MapRoute(null,
            "{category}/Page{page}",
            new { controller = "Product", action = "List" },
            new { page = @"\d+" }
            );
            routes.MapRoute(null, "{controller}/{action}");
        }
    }

我的控制器产品是:

 public class ProductController : Controller
    {
        EFDbContext db = new EFDbContext();
        private IProductsRepository repository;
        public int PageSize = 4;

        public ProductController (IProductsRepository productrepository)
        {
            this.repository = productrepository;
        }
        public ViewResult List(string category, int page = 1)
        {
            ProductsListViewModel model = new ProductsListViewModel()
            {
                Products = repository.Products
                .Where(p => category == null || p.ProductCategory == category || p.MenSubCategory == category)
                    .OrderBy(p => p.ProductID)
                    .Skip((page - 1) * PageSize)
                    .Take(PageSize),
                PagingInfo = new PagingInfo
                {
                    CurrentPage = page,
                    ItemsPerPage = PageSize,
                    TotalItems = category == null ? repository.Products.Count():repository.Products.Where(e => e.ProductCategory == category).Count()
                },
                CurrentCategory = category
            };
            return View(model);
        }

        public PartialViewResult Menu(string subcategory = null )
        {
            ViewBag.SelectedCategory = subcategory;
            IEnumerable<string> categories = repository.MenSubCategories
                .Select(x => x.MenSubCategory)
                .Distinct()
                .OrderBy(x => x);
            return PartialView(categories);
        }
}

我希望我能在这方面得到答案,但我找不到怎么做。

2 个答案:

答案 0 :(得分:0)

使用属性路由,您只需要使用特定的路由模式修饰您的操作方法。

public class ProductController : Controller
 {
     EFDbContext db = new EFDbContext();
     private IProductsRepository repository;
     public int PageSize = 4;

     public ProductController (IProductsRepository productrepository)
     {
          this.repository = productrepository;
     }
     [Route("Product/list/{category}/{page}")]
     public ViewResult List(string category, int page = 1)
     {
       // to do  : Return something
     }
}

上述路由定义会将yourSite/Product/list/phonesyourSite/Product/list/phones/1等请求发送到List操作方法,categorypage的网址段将为映射到方法参数。

要启用属性路由,您需要调用方法MapMvcAttributeRoutes RegisterRoutes方法中的方法。

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

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

答案 1 :(得分:0)

要生成您想要的网址:localhost/Product/List/Cars,您可以创建如下自定义路由:

routes.MapRoute(
    name: "ProductList",
    url: "Product/List/{category}",
    defaults: new { controller = "Product", action = "List" }
);

请记住,自定义路线必须位于最常规的路线(默认模板附带的路线)之前。

关于您的page参数,如果您对此网址感到满意:localhost:3288/Product/List/teste?page=10以上内容已经有效。但是如果你想要这个:localhost:3288/Product/List/teste/10 10表示页码,那么最简单的解决方案就是创建两个不同的路径:

routes.MapRoute(
   name: "ProductList",
   url: "Product/List/{category}",
   defaults: new { controller = "Product", action = "List" }
);

routes.MapRoute(
   name: "ProductListPage",
   url: "Product/List/{category}/{page}",
   defaults: new { controller = "Product", action = "List" , page = UrlParameter.Optional}
);

另一种更简洁的方法是为可选参数创建自定义路径约束。这个问题有很多答案: ASP.NET MVC: Route with optional parameter, but if supplied, must match \d+