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

ASP GridView填充问题求助:DataTable有数据但GridView为空

问题根源分析

你遇到的GridView为空的核心原因是静态WebMethod的特性导致你操作的是一个全新的页面实例,而非当前用户请求的页面实例:

  • ViewDetailsItemOrdersWS是静态方法,你在里面new Index()创建的页面对象,和当前客户端正在交互的页面完全是两个独立的实例。这个新实例里的gvList控件是服务器端新生成的,和前端页面上的gvList没有任何关联,所以即使你绑定了数据,前端也完全看不到变化。
  • 另外,你的前端代码里还有个小bug:获取下拉框值的选择器写错了,$('.<%= ddlTime.ClientID %>')应该改成$('#<%= ddlTime.ClientID %>')(ID选择器用#而非.),否则根本拿不到下拉框的选中值。
解决方案

下面提供两种可行的解决思路,推荐第一种更贴合你当前Ajax的使用场景:

方案一:WebMethod返回JSON数据,前端动态渲染表格(推荐)

这种方式让WebMethod只负责获取数据并返回JSON,前端用JavaScript动态生成表格内容,避免服务器端控件实例不匹配的问题。

后端代码修改

修改WebMethod,将DataTable转换为可序列化的对象列表并返回:

[System.Web.Services.WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static object ViewDetailsItemOrdersWS(String ddlTimeSelectedVal) {
    int val = Convert.ToInt32(ddlTimeSelectedVal);
    DataTable dt = getMenuData(val);
    
    // 将DataTable转换为可序列化的字典列表
    List<Dictionary<string, object>> dataList = new List<Dictionary<string, object>>();
    foreach (DataRow row in dt.Rows) {
        Dictionary<string, object> rowDict = new Dictionary<string, object>();
        foreach (DataColumn col in dt.Columns) {
            rowDict[col.ColumnName] = row[col];
        }
        dataList.Add(rowDict);
    }
    
    return dataList;
}

注:可以删除原来的itemOrder方法,因为不再需要通过页面实例绑定控件了

前端代码修改

修正下拉框选择器,并在Ajax成功回调里动态渲染GridView:

$(document).ready(function () {
    // 修正选择器:用#获取ID
    var dataDDLTime = $('#<%= ddlTime.ClientID %>').val();
    $('#<%= lblItemOrders.ClientID %>').on('click', function () {
        var dataOfDDLTime = JSON.stringify({ ddlTimeSelectedVal: dataDDLTime });
        
        $.ajax({
            type: "POST",
            url: "Index.aspx/ViewDetailsItemOrdersWS",
            data: dataOfDDLTime,
            contentType: 'application/json; charset=utf-8',
            dataType: "json",
            success: function (response) {
                var grid = $('[id$=gvList]');
                var tbody = grid.find('tbody');
                tbody.empty(); // 清空原有内容
                
                // 循环返回的数据生成表格行(请根据你的DataTable列名调整)
                response.d.forEach(function(item) {
                    var row = $('<tr>');
                    // 示例:根据实际列名添加td,比如你的列是OrderId, ItemName, Quantity
                    row.append($('<td>').text(item.OrderId));
                    row.append($('<td>').text(item.ItemName));
                    row.append($('<td>').text(item.Quantity));
                    tbody.append(row);
                });
                
                grid.show(); // 显示GridView
            },
            error: function (err) {
                console.log(err);
            }
        });
    });
});

方案二:使用UpdatePanel实现局部刷新(保留服务器端绑定)

如果你更习惯服务器端控件的绑定方式,可以用UpdatePanel实现局部页面刷新,避免整页回发:

前端ASPX代码修改

将Label(建议换成LinkButton,因为Label默认不支持回发)和GridView放入UpdatePanel:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <asp:LinkButton ID="lblItemOrders" runat="server" Text="查看订单" OnClick="lblItemOrders_Click"></asp:LinkButton>
        <asp:GridView ID="gvList" runat="server" Visible="false"></asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>

后端代码修改

添加LinkButton的点击事件处理方法,直接调用你的itemOrder方法:

protected void lblItemOrders_Click(object sender, EventArgs e) {
    string selectedVal = ddlTime.SelectedValue;
    itemOrder(selectedVal);
}

// 保留你原来的itemOrder方法即可
protected void itemOrder(String ddlTimeSelectedVal) {
    int val = Convert.ToInt32(ddlTimeSelectedVal);
    DataTable s = getMenuData(val);
    gvList.DataSource = s;
    gvList.DataBind();
    gvList.Visible = true;
}

注:这种方式不需要再写jQuery Ajax代码,UpdatePanel会自动处理局部刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:39:03