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

将JavaScript变量传入C#用于SQL查询并返回结果至JS的问题

问题根源:ASP.NET页面生命周期的执行顺序坑到你了!

你遇到的问题本质是服务器端代码和客户端代码的执行时机不匹配:

  • 当页面第一次加载时,服务器就已经把<%=this.ucount%>解析成了初始值(也就是999999999,因为此时invoicenumberhidden还没被JS赋值),这个值直接硬编码到了生成的JavaScript里。
  • 等你点击按钮运行refreshHtml()时,JS确实把选中的行ID塞进了文本框,但此时jsucount已经是页面加载时就固定好的旧值,根本不会重新去调用服务器端的ucount属性。

另外提一句:你原来的SQL拼接写法有严重的SQL注入风险,后面的解决方案里我会帮你改成参数化查询,一定要重视这个问题!

最优解决方案:用AJAX异步调用后台方法

这种方式不需要页面刷新,直接把选中的ID传给服务器获取统计结果,是最流畅的用户体验。

第一步:把统计逻辑改成可被AJAX调用的后台方法

在你的后台代码里添加一个[WebMethod]标记的静态方法(必须是静态的才能被AJAX调用):

using System.Web.Services;

public partial class YourPageName : System.Web.UI.Page
{
    [WebMethod]
    public static int GetUniqueCount(int invoiceNumber)
    {
        // 用参数化查询替代字符串拼接,彻底避免SQL注入
        string commandText = @"SELECT COUNT(*) AS distinct_count 
                               FROM (SELECT DISTINCT [inv_section],[invoice_number], [cust_po] 
                                     FROM [Indigo].[dbo].[invoice_items] 
                                     WHERE invoice_number=@InvoiceNumber) AS I;";
        string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Indigo2.Properties.Settings.Constr"].ConnectionString;
        
        using (SqlConnection conn = new SqlConnection(connectionString))
        using (SqlCommand cmd = new SqlCommand(commandText, conn))
        {
            cmd.Parameters.AddWithValue("@InvoiceNumber", invoiceNumber);
            conn.Open();
            // ExecuteScalar直接返回统计结果,不需要先ExecuteNonQuery(那是执行增删改的)
            int uniqueCount = (int)cmd.ExecuteScalar();
            conn.Close();
            return uniqueCount;
        }
    }

    // 原来的ucount属性如果没有其他地方用到,可以删掉了
}

注意:你原来代码里的cmd.ExecuteNonQuery()是多余的,ExecuteScalar就可以直接获取COUNT的结果,不需要这一步。

第二步:修改JavaScript代码,用AJAX调用这个方法

function refreshHtml() {
    // 获取JQGrid选中的行ID
    var grid = jQuery("#<%= JQGrid1.ClientID %>");
    var rowKey = grid.getGridParam("selrow");
    
    // 先判断有没有选中行
    if (!rowKey) {
        alert("请先选择一行数据!");
        return;
    }

    // 发起AJAX请求
    $.ajax({
        type: "POST",
        // 这里要替换成你的页面文件名,比如你的页面叫Invoice.aspx,就写~/Invoice.aspx/GetUniqueCount
        url: "<%= Page.ResolveUrl("~/YourPageName.aspx/GetUniqueCount") %>",
        // 把参数转成JSON格式,注意参数名要和后台方法的参数名完全一致
        data: JSON.stringify({ invoiceNumber: parseInt(rowKey) }),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(response) {
            // ASP.NET的WebMethod会把返回值包装在d属性里
            var jsucount = response.d;
            alert(jsucount);
            // 这里可以继续写你需要的HTML刷新逻辑
        },
        error: function(xhr, status, error) {
            alert("获取统计数据失败:" + error);
        }
    });
}
为什么原来的方式行不通?再理一遍执行顺序
  1. 用户请求页面 → 服务器跑完所有后台代码(包括ucount属性)→ 生成带有硬编码值的HTML/JS → 发送给客户端。
  2. 客户端加载页面后,JS可以操作DOM(比如给文本框赋值),但这时候服务器已经完成了本次请求的处理,除非发起新的请求(AJAX或者页面回传),否则服务器不会重新执行任何代码。
备选方案:通过页面回传获取值(不推荐,体验差)

如果你实在不想用AJAX,也可以这么做:

  1. 让JS先设置隐藏字段的值,然后让按钮触发页面回传。
  2. 在服务器端的btnDownloadButton_Click事件里计算统计值,把结果存到ViewState或者Session里。
  3. 页面回传后,在客户端用<%= ViewState["UniqueCount"] %>获取结果。
    不过这种方式会导致整个页面刷新,用户体验远不如AJAX,所以优先推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:00:28