由于标题说明了我想要的东西,但具体到某种特定的,我希望有一个像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);
}
}
我希望我能在这方面得到答案,但我找不到怎么做。
答案 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/phones
和yourSite/Product/list/phones/1
等请求发送到List
操作方法,category
和page
的网址段将为映射到方法参数。
要启用属性路由,您需要调用方法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+