You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET WebForms项目SQL数据库产品库存仅扣减1问题求解

问题根源

你的bug是典型的ASP.NET WebForms页面生命周期执行顺序错误导致的:你没有在绑定下拉列表的代码外层加!IsPostBack判断,导致每次页面回发(比如点击下单按钮触发提交操作)时,都会先重新执行下拉列表的绑定逻辑,把用户选中的值重置为默认的第一个选项(也就是1),之后才会执行你写的扣减库存的代码,所以永远只能扣减1。

修复方案

第一步:给下拉列表绑定逻辑加回发判断

找到你WebForm2的Page_Load方法,把下拉列表绑定、产品信息查询的代码都放到if (!IsPostBack)的代码块里,修改后的代码如下:

protected void Page_Load(object sender, EventArgs e)
{
    string productName = Request.QueryString["productname"];
    txt_product13.Text = productName;
    // 只有首次加载页面时才绑定下拉列表,回发时不执行
    if (!IsPostBack)
    {
        var dictionary = new Dictionary<string, object>
        {
            { "@ProductName", productName }
        };
        var parameters = new DynamicParameters(dictionary);
        string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;

        using (var connection = new SqlConnection(CS))
        {
            connection.Open();
            var sql = "SELECT * FROM ProductsDB WHERE ProductName = @ProductName";
            var product = connection.QuerySingle<Product>(sql, parameters);
            CultureInfo EuroCulture = new CultureInfo("fr-FR");
            txt_productprice.Text = product.Price.ToString("c", EuroCulture);

            dropdownlist1.Items.Clear(); // 绑定前先清空原有选项,避免重复追加
            for (int i = 1; i <= product.Quantity; i++)
            {
                dropdownlist1.Items.Add(new ListItem(i.ToString(), i.ToString()));
            }
        }
    }
}

第二步:优化扣减库存代码的安全性和健壮性

你现在的扣减SQL拼接了数值,存在SQL注入风险,同时要加库存不足的校验,避免扣成负数,修改后的扣减代码如下:

// 下单按钮点击事件里的扣减逻辑
string productName = Request.QueryString["productname"];
// 优先取SelectedValue而不是Text,避免显示文本和值不一致的问题
int buyCount = Convert.ToInt32(dropdownlist1.SelectedValue);
var dictionary = new Dictionary<string, object>
{
    {"@ProductName", productName },
    {"@BuyCount", buyCount }
};
var parameters = new DynamicParameters(dictionary);
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (var connection = new SqlConnection(CS))
{
    connection.Open();
    // 用参数化传购买数量,不要拼接字符串,同时加库存判断避免超卖
    var sql = @"UPDATE ProductsDB 
                SET Quantity = Quantity - @BuyCount 
                WHERE ProductName = @ProductName AND Quantity >= @BuyCount";
    int affectRows = connection.Execute(sql, parameters);
    if (affectRows == 0)
    {
        // 库存不足的提示逻辑
        ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('库存不足,下单失败');", true);
    }
    else
    {
        // 下单成功的逻辑
        ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('下单成功');", true);
    }
    // 不需要手动Close,using会自动释放连接
}

额外注意点

  • 下拉列表取值优先用SelectedValue而不是SelectedItem.Text,避免后续修改显示文本时出现取值错误
  • 扣减库存时加Quantity >= @BuyCount的判断可以防止超卖,避免库存出现负数
  • 所有和用户输入相关的参数都要用参数化传递,不要直接拼接SQL,避免SQL注入漏洞

内容的提问来源于stack exchange,提问作者drjoker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:27:00