英文:
Why do I get a HTTP ERROR 404 when listing products by category using ASP.NET Core 6 MVC with pagination?
问题
以下是翻译好的内容:
Why do I have HTTP ERROR 404?
我为什么会出现 HTTP 错误 404?
I am trying to list products by category using ASP.NET Core 6 MVC, and at the same time including a pagination to a view. I am using a ProductsController.cs which has an Index method to display all products, and ProductsByCategory to display only the products with the same category. When I go to: https://localhost:7179/products I got: This localhost page can’t be found, HTTP ERROR 404. atm, I have two categories cacti and bouquet, and can display them when I go to: https://localhost:7179/products/cacti
我正在尝试使用 ASP.NET Core 6 MVC 按类别列出产品,并同时将分页添加到视图中。我使用 ProductsController.cs,其中包含一个 Index 方法来显示所有产品,以及 ProductsByCategory 方法来仅显示具有相同类别的产品。当我访问 https://localhost:7179/products 时,出现了:无法找到此本地主机页面,HTTP 错误 404。目前,我有两个类别,分别是 cacti 和 bouquet,当我访问 https://localhost:7179/products/cacti 时可以显示它们。
I have not yest finished pagination as I have problem displaying all products view.
我还没有完成分页,因为我在显示所有产品视图方面遇到了问题。
Category Model:
类别模型:
Products Controller:
产品控制器:
Index.cshtml View:
Index.cshtml 视图:
ProductsByCategory.cshtml View:
ProductsByCategory.cshtml 视图:
Program.cs endpoints:
Program.cs 端点:
FlowerShopContext.cs:
FlowerShopContext.cs:
英文:
Why do I have HTTP ERROR 404?
I am trying to list products by category using ASP.NET Core 6 MVC, and at the same time including a pagination to a view. I am using a ProductsController.cs which has an Index method to display all products, and ProductsByCategory to display only the products with the same category. When I go to: https://localhost:7179/products I got: This localhost page can’t be found, HTTP ERROR 404. atm, I have two categories cacti and bouquet, and can display them when I go to: https://localhost:7179/products/cacti
I have not yest finished pagination as I have problem displaying all products view.
Category Model:
public class Category
{
public int Id { get; set; }
[Required, MinLength(2, ErrorMessage ="Minimum Length is 2")]
[RegularExpression(@"^[a-zA-Z]+$", ErrorMessage = "Only Letters are allowed")]
public string? Name { get; set; }
public string? Slug { get; set; }
public int Sorting { get; set; }
}
Products Controller:
public class ProductsController : Controller
{
private readonly FlowerShopContext context;
public ProductsController(FlowerShopContext context)
{
this.context = context;
}
//GET /Products/Index
public async Task<IActionResult> Index(int p = 1)
{
int pageSize = 12;
var products = context.Products.OrderByDescending(x => x.Id).Include(x => x.Category).Skip((p - 1) * pageSize).Take(pageSize);
ViewBag.PageNumber = p;
ViewBag.PageRange = pageSize;
ViewBag.TotalPages = (int)Math.Ceiling((decimal)context.Products.Count() / pageSize);
return View(await products.ToListAsync());
}
// GET /products/category
public async Task<IActionResult> ProductsByCategory(string categorySlug, int p = 1)
{
Category category = await context.Categories.Where(x => x.Slug == categorySlug).FirstOrDefaultAsync();
if (category == null) return RedirectToAction("Index");
int pageSize = 6;
var products = context.Products.OrderByDescending(x => x.Id)
.Where(x => x.CategoryId == category.Id)
.Skip((p - 1) * pageSize)
.Take(pageSize);
ViewBag.PageNumber = p;
ViewBag.PageRange = pageSize;
ViewBag.TotalPages = (int)Math.Ceiling((decimal)context.Products.Where(x => x.CategoryId == category.Id).Count() / pageSize);
ViewBag.CategoryName = category.Name;
ViewBag.CategorySlug = categorySlug;
return View(await products.ToListAsync());
}
}
Index.cshtml View:
@model IEnumerable<Product>
@{
ViewData["Title"] = "All Products";
}
<h1>All Products</h1>
<div class="row">
@foreach (var item in Model)
{
<div class="col-4">
<img src="~/media/products/@item.Image" class="image-fluid" width="250" alt=""/>
<h4>@item.Name</h4>
<div>
@Html.Raw(item.Description)
</div>
<p>@item.Price.ToString("c2")</p>
<p>
<a href="#" class="btn btn-outline-primary">Add to cart</a>
</p>
</div>
}
</div>
ProductsByCategory.cshtml View:
@model IEnumerable<Product>
@{
ViewData["Title"] = "Products by category";
}
<h1>Products by category</h1>
<div class="row">
@foreach (var item in Model)
{
<div class="col-4">
<img src="~/media/products/@item.Image" class="image-fluid" width="250" alt=""/>
<h4>@item.Name</h4>
<div>
@Html.Raw(item.Description)
</div>
<p>@item.Price.ToString("c2")</p>
<p>
<a href="#" class="btn btn-outline-primary">Add to cart</a>
</p>
</div>
}
</div>
Program.cs endpoints:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"pages",
"{slug?}",
defaults: new { controller = "Pages", action = "Page" }
);
endpoints.MapControllerRoute(
"products-category",
"products/{categorySlug}",
defaults: new { controller = "Products", action = "ProductsByCategory" }
);
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
FlowerShopContext.cs
public class FlowerShopContext : DbContext
{
public FlowerShopContext(DbContextOptions<FlowerShopContext> options) : base(options)
{
}
public DbSet<Page> Pages { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
}
答案1
得分: 0
我看到有一个名为“Products Controller”的控制器,其中有一个名为“Index”的方法,它接受一个参数“int p = 1”。
但是在您的“Program.cs”端点中,没有匹配的路由,指向“Products/Index/Id”。
因此,我认为这是问题的原因。
英文:
I see that, there is a Products Controller
, with Index
method and it takes a Parameter int p = 1
.
But in your Program.cs
endpoints, there is no matching Route
, which points to Products/Index/Id
.
Hence I think that is causing the Issue.
答案2
得分: 0
我建议你集中精力处理索引和可能返回的 List
学习路由 https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-7.0
[Route("[controller]/[action]")]
public class ProductsController : Controller
{
[Route("~/")]
[Route("/Home")]
[Route("~/Home/Index")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("/products/{page}")]
public IActionResult ListAProducts(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
注意,我没有在 ViewBag 中放任何内容?创建一个分页对象,你可以将它放入你的 "Page" 对象中,其中包含你的分页和 List
英文:
I would suggest you concentrate on the Index and perhaps the List<Product> ? it returns. Get that working then figure out the filter by Category part. - Show the Product class; I assume Product has a Category object or a List<Category> Categories if they can have multiple? Try to make things obvious to your 5 years from now self who maintains it and use good names like Index(int page = 1)
Study routing https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-7.0
[Route("[controller]/[action]")]
public class ProductsController : Controller
{
[Route("~/")]
[Route("/Home")]
[Route("~/Home/Index")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("/products/{page}")]
public IActionResult ListAProducts(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Notice I don't put anything in the ViewBag? Create a pagination object you can put in your "Page" object which contains your Pagination and List<Products>
perhaps
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论