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

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

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

学习路由 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(&quot;[controller]/[action]&quot;)]
public class ProductsController : Controller
{
    [Route(&quot;~/&quot;)]
    [Route(&quot;/Home&quot;)]
    [Route(&quot;~/Home/Index&quot;)]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Route(&quot;/products/{page}&quot;)]
    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&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:

确定