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

回发时ASP.NET GridView的DataView.Table引发空引用异常求助

解决ASP.NET GridView回发时OnRowCreated事件的NullReferenceException问题

错误原因分析

你遇到的NullReferenceException是因为在OnRowCreated事件中,并非所有行类型都有DataItem属性。比如表头行、页脚行,或者你动态插入的小计行,它们的DataItem为null,此时TryCast(e.Row.DataItem, DataRowView)返回null,再访问.DataView.Table就会触发空引用错误。回发时GridView的行创建逻辑会遍历所有行类型,包括非数据行,这就导致首次加载正常(首次加载可能只处理数据行)但回发时出错。

解决方案

  • 先判断行类型,仅处理数据行
    在获取DataItem之前,先检查当前行是否为数据行,跳过非数据行的处理:

    Protected Sub GridView1_RowCreated(sender As Object, e As GridViewRowEventArgs)
        ' 仅处理数据行
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim drv As DataRowView = TryCast(e.Row.DataItem, DataRowView)
            If drv IsNot Nothing Then
                Dim dt As DataTable = drv.DataView.Table
                ' 后续的小计计算逻辑...
            End If
        End If
    End Sub
    
  • 避免从DataItem获取DataTable,改用直接获取数据源
    回发时DataItem可能不可靠,你可以直接从GridView的数据源获取DataTable,或者提前将DataTable存储在ViewState中(如果数据量不大):

    ' 页面加载时绑定数据并存储到ViewState
    Protected Sub Page_Load(sender As Object, e As EventArgs)
        If Not IsPostBack Then
            Dim dt As DataTable = GetYourDataSource() ' 你的数据源获取逻辑
            GridView1.DataSource = dt
            GridView1.DataBind()
            ViewState("GridViewData") = dt
        Else
            ' 回发时重新绑定
            Dim dt As DataTable = TryCast(ViewState("GridViewData"), DataTable)
            If dt IsNot Nothing Then
                GridView1.DataSource = dt
                GridView1.DataBind()
            End If
        End If
    End Sub
    
    ' 在RowCreated中直接从ViewState取DataTable
    Protected Sub GridView1_RowCreated(sender As Object, e As GridViewRowEventArgs)
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim dt As DataTable = TryCast(ViewState("GridViewData"), DataTable)
            If dt IsNot Nothing Then
                ' 后续的小计计算逻辑...
            End If
        End If
    End Sub
    
  • 确保下拉控件回发时数据源正确更新
    如果下拉控件的选择会改变GridView的数据源,回发时需要重新获取对应的数据,而不是直接用ViewState里的旧数据:

    Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As EventArgs)
        ' 根据下拉选择获取新数据
        Dim dt As DataTable = GetDataSourceByDropDownSelection(DropDownList1.SelectedValue)
        GridView1.DataSource = dt
        GridView1.DataBind()
        ViewState("GridViewData") = dt ' 更新ViewState中的数据
    End Sub
    

关键注意点

  • 永远不要假设e.Row.DataItem一定不为null,必须先做非空检查,同时判断行类型。
  • 回发时GridView的数据源必须正确绑定,且数据要与当前下拉选择匹配。
  • 若数据量较大,避免用ViewState存储DataTable,可改用Session或重新从数据库查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:22:41