如何在ASP.NET同一aspx页面执行SQL并循环展示产品列表?
解决ASP.NET WebForms首页展示数据库产品列表的问题
方法一:使用Repeater控件(推荐,符合WebForms开发规范)
Repeater是轻量型自定义数据绑定控件,完美适配你现有卡片布局的需求,代码更易维护。
1. 调整后台代码(home.aspx.cs)
优化数据库操作逻辑,加入资源自动释放机制,同时将数据绑定到Repeater:
using System; using System.Configuration; using System.Data.SqlClient; using System.Web.UI; namespace Try { public partial class WebForm1 : Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) // 仅页面首次加载时绑定数据,避免重复查询 { BindProductList(); } } private void BindProductList() { string connStr = ConfigurationManager.ConnectionStrings["WebConfigConString"].ConnectionString; // 使用using语句自动释放数据库资源,防止内存泄漏 using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); string query = "SELECT * FROM PRODUCT"; using (SqlCommand cmd = new SqlCommand(query, conn)) { using (SqlDataReader reader = cmd.ExecuteReader()) { rptProducts.DataSource = reader; rptProducts.DataBind(); } } } } } }
2. 修改前台aspx代码
将卡片结构嵌套进Repeater的<ItemTemplate>,用<%# Eval("字段名") %>绑定数据库字段值:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="home.aspx.cs" Inherits="Try.WebForm1" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"> <section class="py-5"> <div class="container px-4 px-lg-5 mt-5"> <div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center"> <!-- 新增Repeater控件 --> <asp:Repeater ID="rptProducts" runat="server"> <ItemTemplate> <div class="col mb-5"> <div class="card h-100"> <!-- 产品图片 --> <img class="card-img-top" width="205.99px" height="205.99px" src="data:image/jpg;base64,<%# Convert.ToBase64String((byte[])Eval("ProductImage")) %>" alt="产品图片" /> <!-- 产品详情 --> <div class="card-body p-4"> <div class="text-center"> <!-- 产品名称 --> <h5 class="fw-bolder"><%# Eval("ProductName") %></h5> <!-- 产品价格 --> <%# Eval("ProductPrice") %><br/> <%# Eval("ProductDescription") %> </div> </div> <!-- 操作按钮 --> <div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <div class="text-center"> <a class="btn btn-outline-dark mt-auto" href='productDetails.aspx?id=<%# Eval("ProductId") %>'>查看详情</a> </div><br /> <div class="text-center"> <a class="btn btn-outline-dark mt-auto" href='home.aspx?addcart=<%# Eval("ProductId") %>'>加入购物车</a> </div> </div> </div> </div> </ItemTemplate> </asp:Repeater> </div> </div> </section> </asp:Content>
注意:将代码中的
ProductImage、ProductName、ProductPrice等字段名替换为你数据库表中的实际字段名。
方法二:使用内联代码直接循环输出
如果偏好原生代码循环的方式,可按以下步骤调整:
1. 修改后台代码
将数据阅读器声明为页面的protected成员,让前台可以访问:
using System; using System.Configuration; using System.Data.SqlClient; using System.Web.UI; namespace Try { public partial class WebForm1 : Page { protected SqlDataReader productReader; protected void Page_Load(object sender, EventArgs e) { string connStr = ConfigurationManager.ConnectionStrings["WebConfigConString"].ConnectionString; SqlConnection conn = new SqlConnection(connStr); conn.Open(); string query = "SELECT * FROM PRODUCT"; SqlCommand cmd = new SqlCommand(query, conn); productReader = cmd.ExecuteReader(); } // 页面卸载时手动释放数据库资源 protected void Page_Unload(object sender, EventArgs e) { if (productReader != null && !productReader.IsClosed) { productReader.Close(); productReader.Dispose(); } if (productReader?.Connection != null && productReader.Connection.State == System.Data.ConnectionState.Open) { productReader.Connection.Close(); productReader.Connection.Dispose(); } } } }
2. 修改前台aspx代码
用<% while (productReader.Read()) { %>和<% } %>包裹循环块,用<%= productReader["字段名"] %>读取字段值:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="home.aspx.cs" Inherits="Try.WebForm1" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"> <section class="py-5"> <div class="container px-4 px-lg-5 mt-5"> <div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center"> <% while (productReader.Read()) { %> <div class="col mb-5"> <div class="card h-100"> <!-- 产品图片 --> <img class="card-img-top" width="205.99px" height="205.99px" src="data:image/jpg;base64,<%= Convert.ToBase64String((byte[])productReader["ProductImage"]) %>" alt="产品图片" /> <!-- 产品详情 --> <div class="card-body p-4"> <div class="text-center"> <!-- 产品名称 --> <h5 class="fw-bolder"><%= productReader["ProductName"] %></h5> <!-- 产品价格 --> <%= productReader["ProductPrice"] %><br/> <%= productReader["ProductDescription"] %> </div> </div> <!-- 操作按钮 --> <div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <div class="text-center"> <a class="btn btn-outline-dark mt-auto" href='productDetails.aspx?id=<%= productReader["ProductId"] %>'>查看详情</a> </div><br /> <div class="text-center"> <a class="btn btn-outline-dark mt-auto" href='home.aspx?addcart=<%= productReader["ProductId"] %>'>加入购物车</a> </div> </div> </div> </div> <% } %> </div> </div> </section> </asp:Content>
关键注意事项
- 字段匹配:所有代码中的字段名必须与数据库表的实际字段完全一致,否则会抛出异常。
- 资源释放:方法一用
using自动释放资源,方法二需在Page_Unload手动清理,避免数据库连接泄漏。 - 安全防护:若后续需要添加查询参数,必须使用参数化查询,防止SQL注入攻击。
- 错误处理:可在后台代码中添加
try-catch块捕获异常,例如:
try { // 数据库操作代码 } catch (Exception ex) { Response.Write("产品加载失败:" + ex.Message); }
内容的提问来源于stack exchange,提问作者YUNG FOOK YONG
相关产品推荐
相关产品推荐

