点击表单按钮后Dataset为NULL的VB2017 WebForm问题排查
这是Web Forms开发里非常典型的生命周期问题:每次页面回发(比如点击Save按钮),ASP.NET都会创建NWtest页面类的全新实例。你定义的DS、DA这些成员变量属于类实例,所以回发后这些变量都会被重新初始化,默认值就是Nothing(对应C#的null),这就是点击按钮后调用testDS()触发空引用异常的根本原因。
为什么第一次Page_Load时没问题?因为第一次加载是Not IsPostBack的场景,你调用了GETNWDS()初始化了DS;但回发时,IsPostBack为True,Page_Load里的代码不会执行GETNWDS(),而新实例的DS从未被赋值,自然是null。
根据你的需求,有几种常用的处理方式:
1. 回发时重新获取DataSet(最简单直接)
如果数据不需要跨多次请求保留,在按钮点击事件里先重新调用GETNWDS()初始化DS,再执行testDS():
Protected Sub SaveButton_Click(sender As Object, e As EventArgs) Handles SaveButton.Click ' 回发时重新从数据库获取数据初始化DS GETNWDS() ' 现在DS已经有值了,可以安全调用testDS() testDS() End Sub
优点:实现简单,不需要额外的状态存储;缺点:每次回发都要查询数据库,适合数据量小、查询开销低的场景。
2. 用ViewState保存DataSet(适合单次回发保留数据)
把DS序列化后存储在ViewState中,回发时再取出来复用:
修改Page_Load和GETNWDS()的逻辑:
Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Call GETNWDS() ' 将DataSet存入ViewState ViewState("CustomerDataSet") = DS Call testDS() Else ' 回发时从ViewState取出DataSet并赋值给DS If ViewState("CustomerDataSet") IsNot Nothing Then DS = DirectCast(ViewState("CustomerDataSet"), DataSet) End If End Sub End Sub
优点:数据存在客户端页面中,不占用服务器内存;缺点:如果DataSet较大,会增加页面的HTML大小,影响加载速度,且ViewState可能被篡改(敏感数据不建议用这种方式)。
3. 用Session保存DataSet(适合跨多次请求保留数据)
如果需要在多个回发请求中复用DataSet,可以存在Session里:
Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Call GETNWDS() ' 将DataSet存入Session Session("CustomerDataSet") = DS Call testDS() Else ' 回发时从Session取出DataSet If Session("CustomerDataSet") IsNot Nothing Then DS = DirectCast(Session("CustomerDataSet"), DataSet) End If End Sub End Sub
优点:可以跨多个请求保留数据;缺点:会占用服务器内存,Session有过期时间,且要注意并发场景下的Session冲突问题。
不管用哪种方式,都要在testDS()里增加空值判断,避免即使处理了仍可能出现的空引用:
Public Sub testDS() Try If DS IsNot Nothing AndAlso DS.Tables.Count > 0 AndAlso DS.Tables(0).Rows.Count > 0 Then Dim v As String v = "in DS= " + DS.Tables(0).Rows(0).Item("ContactName").ToString Textbox.Text = v Else Textbox.Text = "DataSet或数据表为空" End If Catch x As Exception Textbox.Text = x.ToString End Try End Sub
内容的提问来源于stack exchange,提问作者Ton Daamen

