我使用ASP.NET Core 6 MVC分页列出产品按类别时为什么会出现HTTP错误404?

huangapple go评论106阅读模式
英文:

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:

  1. public class Category
  2. {
  3. public int Id { get; set; }
  4. [Required, MinLength(2, ErrorMessage ="Minimum Length is 2")]
  5. [RegularExpression(@"^[a-zA-Z]+$", ErrorMessage = "Only Letters are allowed")]
  6. public string? Name { get; set; }
  7. public string? Slug { get; set; }
  8. public int Sorting { get; set; }
  9. }

Products Controller:

  1. public class ProductsController : Controller
  2. {
  3. private readonly FlowerShopContext context;
  4. public ProductsController(FlowerShopContext context)
  5. {
  6. this.context = context;
  7. }
  8. //GET /Products/Index
  9. public async Task<IActionResult> Index(int p = 1)
  10. {
  11. int pageSize = 12;
  12. var products = context.Products.OrderByDescending(x => x.Id).Include(x => x.Category).Skip((p - 1) * pageSize).Take(pageSize);
  13. ViewBag.PageNumber = p;
  14. ViewBag.PageRange = pageSize;
  15. ViewBag.TotalPages = (int)Math.Ceiling((decimal)context.Products.Count() / pageSize);
  16. return View(await products.ToListAsync());
  17. }
  18. // GET /products/category
  19. public async Task<IActionResult> ProductsByCategory(string categorySlug, int p = 1)
  20. {
  21. Category category = await context.Categories.Where(x => x.Slug == categorySlug).FirstOrDefaultAsync();
  22. if (category == null) return RedirectToAction("Index");
  23. int pageSize = 6;
  24. var products = context.Products.OrderByDescending(x => x.Id)
  25. .Where(x => x.CategoryId == category.Id)
  26. .Skip((p - 1) * pageSize)
  27. .Take(pageSize);
  28. ViewBag.PageNumber = p;
  29. ViewBag.PageRange = pageSize;
  30. ViewBag.TotalPages = (int)Math.Ceiling((decimal)context.Products.Where(x => x.CategoryId == category.Id).Count() / pageSize);
  31. ViewBag.CategoryName = category.Name;
  32. ViewBag.CategorySlug = categorySlug;
  33. return View(await products.ToListAsync());
  34. }
  35. }

Index.cshtml View:

  1. @model IEnumerable<Product>
  2. @{
  3. ViewData["Title"] = "All Products";
  4. }
  5. <h1>All Products</h1>
  6. <div class="row">
  7. @foreach (var item in Model)
  8. {
  9. <div class="col-4">
  10. <img src="~/media/products/@item.Image" class="image-fluid" width="250" alt=""/>
  11. <h4>@item.Name</h4>
  12. <div>
  13. @Html.Raw(item.Description)
  14. </div>
  15. <p>@item.Price.ToString("c2")</p>
  16. <p>
  17. <a href="#" class="btn btn-outline-primary">Add to cart</a>
  18. </p>
  19. </div>
  20. }
  21. </div>

ProductsByCategory.cshtml View:

  1. @model IEnumerable<Product>
  2. @{
  3. ViewData["Title"] = "Products by category";
  4. }
  5. <h1>Products by category</h1>
  6. <div class="row">
  7. @foreach (var item in Model)
  8. {
  9. <div class="col-4">
  10. <img src="~/media/products/@item.Image" class="image-fluid" width="250" alt=""/>
  11. <h4>@item.Name</h4>
  12. <div>
  13. @Html.Raw(item.Description)
  14. </div>
  15. <p>@item.Price.ToString("c2")</p>
  16. <p>
  17. <a href="#" class="btn btn-outline-primary">Add to cart</a>
  18. </p>
  19. </div>
  20. }
  21. </div>

Program.cs endpoints:

  1. app.UseEndpoints(endpoints =>
  2. {
  3. endpoints.MapControllerRoute(
  4. "pages",
  5. "{slug?}",
  6. defaults: new { controller = "Pages", action = "Page" }
  7. );
  8. endpoints.MapControllerRoute(
  9. "products-category",
  10. "products/{categorySlug}",
  11. defaults: new { controller = "Products", action = "ProductsByCategory" }
  12. );
  13. endpoints.MapControllerRoute(
  14. name: "areas",
  15. pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
  16. );
  17. endpoints.MapControllerRoute(
  18. name: "default",
  19. pattern: "{controller=Home}/{action=Index}/{id?}");
  20. });

FlowerShopContext.cs

  1. public class FlowerShopContext : DbContext
  2. {
  3. public FlowerShopContext(DbContextOptions<FlowerShopContext> options) : base(options)
  4. {
  5. }
  6. public DbSet<Page> Pages { get; set; }
  7. public DbSet<Category> Categories { get; set; }
  8. public DbSet<Product> Products { get; set; }
  9. }

答案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 ? 先让它们正常工作,然后再考虑按类别筛选的部分。 - 显示 Product 类;我假设 Product 有一个 Category 对象或一个 List Categories,如果它们可以有多个的话?尽量让事情对将来的自己变得明显,并使用好的名称,比如 Index(int page = 1)

学习路由 https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-7.0

  1. [Route("[controller]/[action]")]
  2. public class ProductsController : Controller
  3. {
  4. [Route("~/")]
  5. [Route("/Home")]
  6. [Route("~/Home/Index")]
  7. public IActionResult Index()
  8. {
  9. return ControllerContext.MyDisplayRouteInfo();
  10. }
  11. [Route("/products/{page}")]
  12. public IActionResult ListAProducts(int page)
  13. {
  14. return ControllerContext.MyDisplayRouteInfo(page);
  15. }
  16. public IActionResult About()
  17. {
  18. return ControllerContext.MyDisplayRouteInfo();
  19. }
  20. }

注意,我没有在 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

  1. [Route(&quot;[controller]/[action]&quot;)]
  2. public class ProductsController : Controller
  3. {
  4. [Route(&quot;~/&quot;)]
  5. [Route(&quot;/Home&quot;)]
  6. [Route(&quot;~/Home/Index&quot;)]
  7. public IActionResult Index()
  8. {
  9. return ControllerContext.MyDisplayRouteInfo();
  10. }
  11. [Route(&quot;/products/{page}&quot;)]
  12. public IActionResult ListAProducts(int page)
  13. {
  14. return ControllerContext.MyDisplayRouteInfo(page);
  15. }
  16. public IActionResult About()
  17. {
  18. return ControllerContext.MyDisplayRouteInfo();
  19. }
  20. }

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&lt;Products&gt; perhaps

huangapple
  • 本文由 发表于 2023年5月30日 03:04:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76359819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定