后台商品列表功能开发全攻略

实现后台商品列表功能的关键步骤

数据模型设计

创建商品实体类(Product.cs),包含基础字段如Id、Name、Price、Stock等。使用数据注解进行验证:

public class Product
{
    public int Id { get; set; }
    
    [Required]
    [StringLength(100)]
    public string Name { get; set; }
    
    [Range(0.01, double.MaxValue)]
    public decimal Price { get; set; }
    
    public int Stock { get; set; }
    
    [DataType(DataType.DateTime)]
    public DateTime CreatedDate { get; set; }
}

数据库上下文配置

在ApplicationDbContext中配置DbSet和可能的种子数据:

public class ApplicationDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>().HasData(
            new Product { Id = 1, Name = "示例商品", Price = 99.99m, Stock = 100 }
        );
    }
}

控制器实现

创建ProductsController并实现CRUD操作。列表功能需包含分页和搜索:

public class ProductsController : Controller
{
    private readonly ApplicationDbContext _context;
    
    public ProductsController(ApplicationDbContext context)
    {
        _context = context;
    }
    
    public async Task<IActionResult> Index(int page = 1, string searchString = "")
    {
        var query = _context.Products.AsQueryable();
        
        if (!string.IsNullOrEmpty(searchString))
        {
            query = query.Where(p => p.Name.Contains(searchString));
        }
        
        var pageSize = 10;
        var totalItems = await query.CountAsync();
        var products = await query.Skip((page - 1) * pageSize)
                                .Take(pageSize)
                                .ToListAsync();
        
        var model = new ProductListViewModel
        {
            Products = products,
            PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = pageSize,
                TotalItems = totalItems
            },
            SearchString = searchString
        };
        
        return View(model);
    }
}

视图模型设计

创建专用的视图模型类处理分页和搜索参数:

public class ProductListViewModel
{
    public IEnumerable<Product> Products { get; set; }
    public PagingInfo PagingInfo { get; set; }
    public string SearchString { get; set; }
}

public class PagingInfo
{
    public int TotalItems { get; set; }
    public int ItemsPerPage { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages => (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage);
}

Razor视图实现

在Views/Products/Index.cshtml中实现交互界面:

@model ProductListViewModel

<form asp-action="Index" method="get">
    <div class="input-group mb-3">
        <input type="text" class="form-control" name="searchString" value="@Model.SearchString"/>
        <button type="submit" class="btn btn-primary">搜索</button>
    </div>
</form>

<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>名称</th>
            <th>价格</th>
            <th>库存</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Products)
        {
            <tr>
                <td>@item.Id</td>
                <td>@item.Name</td>
                <td>@item.Price.ToString("C")</td>
                <td>@item.Stock</td>
            </tr>
        }
    </tbody>
</table>

<div class="pagination">
    @for (int i = 1; i <= Model.PagingInfo.TotalPages; i++)
    {
        <a href="@Url.Action("Index", new { page = i, searchString = Model.SearchString })" 
           class="@(i == Model.PagingInfo.CurrentPage ? "active" : "")">
            @i
        </a>
    }
</div>

性能优化技巧

使用异步编程模式提高吞吐量,添加适当的索引提升查询效率:

// 在DbContext的OnModelCreating中添加
modelBuilder.Entity<Product>()
    .HasIndex(p => p.Name);
    
// 使用AsNoTracking()减少内存占用
var products = await query.AsNoTracking().ToListAsync();

安全性考虑

添加[Authorize]特性限制访问权限,防止CSRF攻击:

[Authorize(Roles = "Admin")]
public class ProductsController : Controller
{
    // 控制器代码
}

// 在视图中添加防伪令牌
<form asp-action="Create" method="post">
    @Html.AntiForgeryToken()
    <!-- 表单字段 -->
</form>

前端增强

引入jQuery DataTables实现客户端分页和排序,或使用AJAX加载数据:

$(document).ready(function() {
    $('#productsTable').DataTable({
        "processing": true,
        "serverSide": true,
        "ajax": {
            "url": "/Products/GetProducts",
            "type": "POST"
        }
    });
});

单元测试策略

编写控制器和服务的单元测试,确保核心逻辑正确:

[Fact]
public async Task Index_ReturnsViewResult_WithProductList()
{
    // 准备
    var mockContext = new Mock<ApplicationDbContext>();
    mockContext.Setup(c => c.Products).Returns(MockDbSet(new List<Product>{
        new Product { Id = 1, Name = "Test" }
    }));
    
    // 执行
    var controller = new ProductsController(mockContext.Object);
    var result = await controller.Index();
    
    // 断言
    var viewResult = Assert.IsType<ViewResult>(result);
    var model = Assert.IsAssignableFrom<ProductListViewModel>(viewResult.Model);
    Assert.Single(model.Products);
}

BbS.okacop060.info/PoSt/1120_603485.HtM
BbS.okacop061.info/PoSt/1120_182119.HtM
BbS.okacop062.info/PoSt/1120_245981.HtM
BbS.okacop063.info/PoSt/1120_886097.HtM
BbS.okacop065.info/PoSt/1120_462709.HtM
BbS.okacop066.info/PoSt/1120_128011.HtM
BbS.okacop067.info/PoSt/1120_982004.HtM
BbS.okacop068.info/PoSt/1120_690279.HtM
BbS.okacop069.info/PoSt/1120_298969.HtM
BbS.okacop070.info/PoSt/1120_896678.HtM
BbS.okacop060.info/PoSt/1120_233726.HtM
BbS.okacop061.info/PoSt/1120_545855.HtM
BbS.okacop062.info/PoSt/1120_853919.HtM
BbS.okacop063.info/PoSt/1120_563955.HtM
BbS.okacop065.info/PoSt/1120_523815.HtM
BbS.okacop066.info/PoSt/1120_984390.HtM
BbS.okacop067.info/PoSt/1120_046860.HtM
BbS.okacop068.info/PoSt/1120_806353.HtM
BbS.okacop069.info/PoSt/1120_005359.HtM
BbS.okacop070.info/PoSt/1120_221332.HtM
BbS.okacop060.info/PoSt/1120_457526.HtM
BbS.okacop061.info/PoSt/1120_368218.HtM
BbS.okacop062.info/PoSt/1120_760803.HtM
BbS.okacop063.info/PoSt/1120_735362.HtM
BbS.okacop065.info/PoSt/1120_764778.HtM
BbS.okacop066.info/PoSt/1120_002233.HtM
BbS.okacop067.info/PoSt/1120_526591.HtM
BbS.okacop068.info/PoSt/1120_150214.HtM
BbS.okacop069.info/PoSt/1120_665620.HtM
BbS.okacop070.info/PoSt/1120_940601.HtM
BbS.okacop060.info/PoSt/1120_132551.HtM
BbS.okacop061.info/PoSt/1120_249846.HtM
BbS.okacop062.info/PoSt/1120_558915.HtM
BbS.okacop063.info/PoSt/1120_518891.HtM
BbS.okacop065.info/PoSt/1120_100585.HtM
BbS.okacop066.info/PoSt/1120_518524.HtM
BbS.okacop067.info/PoSt/1120_266546.HtM
BbS.okacop068.info/PoSt/1120_243416.HtM
BbS.okacop069.info/PoSt/1120_671909.HtM
BbS.okacop070.info/PoSt/1120_202702.HtM
BbS.okacop060.info/PoSt/1120_447569.HtM
BbS.okacop061.info/PoSt/1120_435173.HtM
BbS.okacop062.info/PoSt/1120_608323.HtM
BbS.okacop063.info/PoSt/1120_367624.HtM
BbS.okacop065.info/PoSt/1120_976891.HtM
BbS.okacop066.info/PoSt/1120_567753.HtM
BbS.okacop067.info/PoSt/1120_427687.HtM
BbS.okacop068.info/PoSt/1120_925356.HtM
BbS.okacop069.info/PoSt/1120_939701.HtM
BbS.okacop070.info/PoSt/1120_279304.HtM
BbS.okacop060.info/PoSt/1120_874102.HtM
BbS.okacop061.info/PoSt/1120_780475.HtM
BbS.okacop062.info/PoSt/1120_823183.HtM
BbS.okacop063.info/PoSt/1120_623005.HtM
BbS.okacop065.info/PoSt/1120_905104.HtM
BbS.okacop066.info/PoSt/1120_164292.HtM
BbS.okacop067.info/PoSt/1120_204317.HtM
BbS.okacop068.info/PoSt/1120_089871.HtM
BbS.okacop069.info/PoSt/1120_925104.HtM
BbS.okacop070.info/PoSt/1120_139720.HtM
BbS.okacop060.info/PoSt/1120_010802.HtM
BbS.okacop061.info/PoSt/1120_987809.HtM
BbS.okacop062.info/PoSt/1120_948334.HtM
BbS.okacop063.info/PoSt/1120_609916.HtM
BbS.okacop065.info/PoSt/1120_313409.HtM
BbS.okacop066.info/PoSt/1120_735429.HtM
BbS.okacop067.info/PoSt/1120_211166.HtM
BbS.okacop068.info/PoSt/1120_001976.HtM
BbS.okacop069.info/PoSt/1120_481574.HtM
BbS.okacop070.info/PoSt/1120_606347.HtM
BbS.okacop071.info/PoSt/1120_297532.HtM
BbS.okacop072.info/PoSt/1120_755147.HtM
BbS.okacop073.info/PoSt/1120_101834.HtM
BbS.okacop074.info/PoSt/1120_670322.HtM
BbS.okacop075.info/PoSt/1120_599764.HtM
BbS.okacop076.info/PoSt/1120_503734.HtM
BbS.okacop077.info/PoSt/1120_494874.HtM
BbS.okacop078.info/PoSt/1120_518653.HtM
BbS.okacop079.info/PoSt/1120_560001.HtM
BbS.okacop080.info/PoSt/1120_903501.HtM

#牛客AI配图神器#

全部评论

相关推荐

双尔:你就写拥有ai开发经历,熟练运用提示词,优化ai,提高ai回答质量
点赞 评论 收藏
分享
10-30 16:31
重庆大学 Java
代码飞升_不回私信人...:你说你善于学习,大家都会说。你说你是985,985会替你表达一切
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务