Object reference not set to an instance of an object

paulhudson

Newcomer
Joined
Jan 11, 2005
Messages
17
I have a datagrid bound to a dataset. When selecting the onupdatecommand to accept changes I get the error message:

"Object reference not set to an instance of an object"

The datagrid:
Code:
<asp:DataGrid id="dgr1" runat="server" 
DataKeyField="PlayerID"
OnEditCommand="DoItemEdit"
OnUpdateCommand="DoItemUpdate"
OnCancelCommand="DoItemCancel">

Visual Basic:
Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	tpDataSet.AcceptChanges()
	dgr1.DataSource = dsTeamPlayer.Tables("LastTeamPlayers")
	dgr1.DataBind()
End Sub

Any ideas? Any help would make my day!
 
Last edited by a moderator:
Which line does the error occur on? If you step through the code in the debugger what are the values of the objects on the line that the error happens?
Are you sure you are assigning valid instances to the variables?
 
error line

The error occurs at the line:
tpDataSet.AcceptChanges()

Unsure how to answer your other questions. I'm fairly recent to ASP.NET and I haven't been using visual studio.

If you can advise how to get more information it would be much appreciated!

All I can give is the stack trace:

[NullReferenceException: Object reference not set to an instance of an object.]
ASP.TeamList_aspx.DoItemUpdate(Object sender, DataGridCommandEventArgs e) in c:\admin\teamlist.aspx:186
System.Web.UI.WebControls.DataGrid.OnUpdateCommand(DataGridCommandEventArgs e) +111
System.Web.UI.WebControls.DataGrid.OnBubbleEvent(Object source, EventArgs e) +553
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +31
System.Web.UI.WebControls.DataGridItem.OnBubbleEvent(Object source, EventArgs e) +120
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +31
System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +122
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +288
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +5
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +166
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5157
 
Don know if this code is the same as from your previous code, but where do you declare tpDataSet? By the time the code goes into this sub, has tpDataSet been declared with the new construct? like, tpDataSet = new dataset ?
 
kahlua001

The code is based on my previous posts - but I have been butchering it in order to get it working (unsuccessfully). Below is the full code - it is all there! I have a couple of fundamental flaws that I can identify.

On first load all goes well, I fill a dataset from db then create a new dataset copying the data from original dataset and add another column. I have done this as a method of testing, don't see the need to keep it.

The datagrid is bound to this data and all looks good. Now in the OnEditCommand, if I call the original sub BindData it goes into the edit mode as I expect (problem is the dataset is reloaded from database - so even if accept changes were successful they would be wiped!)

If I try to bind the dataset to datagrid outside of the sub that creates dataset, I get the error message as originally posted.

I do not understand how I use the dataset after page has been reloaded. I feel like I am missing a fundamental piece of the jigsaw.

Hope my confusion makes sense....
Visual Basic:
Public sKey as string
Public MatchDataID as string
Public dsTeamPlayer As Dataset
Public dsCopy As DataSet
Public tpDataSet as Dataset
Public Sub Page_Load()
	If Not Page.IsPostback Then
		BindData
	End If
End Sub

Public sub BindData()
	MatchDataID = Session("MatchDataID")
	sKey = Session("TeamID")
 	Dim oConnect As New OleDbConnection(ConfigurationSettings.AppSettings("connString"))
  	Dim oDR As OleDbDataAdapter = New OleDbDataAdapter
	oDR.SelectCommand = New OleDbCommand("spTeamLineUp" , oConnect)
	oDR.SelectCommand.CommandType = CommandType.StoredProcedure
	Dim oParam As OleDbParameter = oDR.SelectCommand.Parameters.Add("@ParamID", OleDbType.Integer)
	oParam.Value = sKey
	oParam.Direction = ParameterDirection.Input
	dsTeamPlayer = New Dataset() 
	oDR.MissingSchemaAction = MissingSchemaAction.AddWithKey
	oDR.Fill(dsTeamPlayer, "LastTeamPlayers")
	NewDataSet
End Sub

Public Sub NewDataSet	
	Dim dtTeamPlayers As DataTable = new DataTable("TeamPlayers")
	Dim tpDataColumn As DataColumn
	Dim tpDataRow As DataRow

	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.Int32")
	tpDataColumn.ColumnName = "PNumber"
	tpDataColumn.ReadOnly = False
	tpDataColumn.Unique = True
	tpDataColumn.AutoIncrement = False

	dtTeamPlayers.Columns.Add(tpDataColumn)

	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.Int32")
	tpDataColumn.ColumnName = "PlayerID"
	tpDataColumn.ReadOnly = False
	tpDataColumn.Unique = True
	tpDataColumn.AutoIncrement = False

	dtTeamPlayers.Columns.Add(tpDataColumn)

	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.String")
	tpDataColumn.ColumnName = "PlayerName"
	tpDataColumn.ReadOnly = False
	tpDataColumn.Unique = True
	tpDataColumn.AutoIncrement = False
	
	dtTeamPlayers.Columns.Add(tpDataColumn)
	
	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.String")
	tpDataColumn.ColumnName = "TPosition"
	tpDataColumn.ReadOnly = False
	tpDataColumn.Unique = True
	tpDataColumn.AutoIncrement = False

	dtTeamPlayers.Columns.Add(tpDataColumn)

	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.Int32")
	tpDataColumn.ColumnName = "TPositionID"
	tpDataColumn.ReadOnly = False
	tpDataColumn.Unique = True
	tpDataColumn.AutoIncrement = False
	
	dtTeamPlayers.Columns.Add(tpDataColumn)

	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.Int32")
	tpDataColumn.ColumnName = "Goals"
	tpDataColumn.ReadOnly = False
	tpDataColumn.Unique = False
	tpDataColumn.AutoIncrement = False

	dtTeamPlayers.Columns.Add(tpDataColumn)

	dim tpDataSet As DataSet = New DataSet()
	tpDataSet.Tables.Add(dtTeamPlayers)

	Dim PrimaryKeyColumns(0) As DataColumn
	PrimaryKeyColumns(0)= dtTeamPlayers.Columns("PlayerID")
	dtTeamPlayers.PrimaryKey = PrimaryKeyColumns
	
	Dim DataRowCopy as DataRow
	for each DataRowCopy in dsTeamPlayer.Tables(0).Rows
	tpDataRow = dtTeamPlayers.NewRow()
	tpDataRow("PNumber") = DataRowCopy("PNumber")
	tpDataRow("PlayerID") = DataRowCopy("PlayerID")
	tpDataRow("PlayerName") = DataRowCopy("PlayerName")
	tpDataRow("TPosition") = DataRowCopy("TPosition")
	tpDataRow("TPositionID") = DataRowCopy("TPositionID")
	tpDataRow("Goals") = "0"
	dtTeamPlayers.Rows.Add(tpDataRow)
	next
	dgr1.DataSource = tpDataSet.Tables("TeamPlayers")
	dgr1.DataBind()
End sub 

Function GetTeamPositions()
 	Dim oConnect As New OleDbConnection(ConfigurationSettings.AppSettings("connString"))
  	Dim oCommand As New OleDbCommand("spTeamPositions", oConnect)
	oCommand.commandType = CommandType.StoredProcedure
	Try
		oConnect.Open()
		Return oCommand.ExecuteReader(CommandBehavior.CloseConnection)
 		Catch oErr As Exception
  		If oConnect.State <> ConnectionState.Closed Then
   			oConnect.Close()
  		End If
		lblErr.Text = oErr.Message & "<p/>"
	End Try
End function

Function GetTeamPlayers()
 	Dim oConnect As New OleDbConnection(ConfigurationSettings.AppSettings("connString"))
  	Dim oCommand As New OleDbCommand("spTeamPlayerList", oConnect)
	oCommand.commandType = CommandType.StoredProcedure
	dim oParam as OleDbParameter
	oParam = oCommand.Parameters.Add("@ParamID", _
	OleDbType.Integer)
	oParam.Direction = ParameterDirection.Input
	oParam.Value = sKey
	Try
		oConnect.Open()
		Return oCommand.ExecuteReader(CommandBehavior.CloseConnection)
 		Catch oErr As Exception
  		If oConnect.State <> ConnectionState.Closed Then
   			oConnect.Close()
  		End If
		lblErr.Text = oErr.Message & "<p/>"
	End Try
End function

Sub DoItemEdit(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs)
    dgr1.EditItemIndex = CInt(E.Item.ItemIndex)
	BindData ' [COLOR=Red]this displays the dropdownlists/text boxes of edit mode! But it is refreshing the dataset to original state each time![/COLOR]
End Sub

Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	tpDataSet.AcceptChanges() '[COLOR=Red]this is where to obj ref error comes in![/COLOR]
	dgr1.DataSource = tpDataSet.Tables("TeamPlayers")
	dgr1.DataBind()
End Sub

Sub DoItemCancel(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs)
    dgr1.EditItemIndex = -1
	BindData
End Sub
 
Last edited by a moderator:
Becuase you created your dataset inside a sub, it only exists in that sub. So upon postback, it no longer exists, you need to recreate it. Or, you could load the dataset in a viewstate or session variable, then on postback the persisted data would be available to you again.
 
acceptchanges to dataset

I have now used session state to hold the dataset. So now the dataset is displayed in edit mode ok. But on selecting update the dataset has no changes applied. No errors occur.
Visual Basic:
Sub DoItemEdit(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs)
    dgr1.EditItemIndex = CInt(E.Item.ItemIndex)
	Dim tpDataSet As New DataSet()
	tpDataSet = Session("tpDataSet")	
	dgr1.DataSource = tpDataSet.Tables("TeamPlayers")
	dgr1.DataBind()
End Sub

Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	Dim tpDataSet As New DataSet()
	tpDataSet = Session("tpDataSet")	
	tpDataSet.AcceptChanges()
	dgr1.DataSource = tpDataSet.Tables("TeamPlayers")
	dgr1.DataBind()
End Sub
 
Last edited by a moderator:
After you update your dataset, do you reset the session variable with your new dataset?

Code:
'Updating dataset
Session("Dataset") = MyDataset

Also..it might be better to create a page level dataset variable and in your page_load, grab it from your session or create it.

Code:
Private myDataset as dataset

Private sub page_load(e as .., s as..)
   If Not IsPostBack Then
      'First time to this page, create the dataset
      myDataset = new dataset
      Session("myDataSet") = myDataset
   Else
      'Posting back, dataset already exists, grab from session
      myDataset = session("myDataSet")
   End If
End Sub

Then in your datagrtid events, just make sure you reset the session with the new dataset.
 
acceptchanges to dataset

I have done as suggested with the page load, and I have posted my update script below.

I call the acceptchanges, then refresh the session with the dataset and then bind the datagrid to the same dataset - but no changes are shown.

Code:
Visual Basic:
Sub DoItemUpdate(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	tpDataSet.AcceptChanges()
	Session("tpDataSet") = tpDataSet
             dgr1.EditItemIndex = -1
	dgr1.DataSource = tpDataSet.Tables("TeamPlayers")
	dgr1.DataBind()
 
Last edited by a moderator:
Ok, so I have been a bit dippy on this one. When leaving edit mode of datagrid, I need to extract the new values and modify the relevant row in the dataset. I've got this far, with one slight problem.

When I try to find the row using a uniqueID I get an error message:

Input string was not in a correct format

The column is created thus:
Visual Basic:
	tpDataColumn = New DataColumn()
	tpDataColumn.DataType = System.Type.GetType("System.Int32")
	tpDataColumn.ColumnName = "UniqueID"
	tpDataColumn.ReadOnly = True
	tpDataColumn.Unique = True
	tpDataColumn.AutoIncrement = True

And the find command is (error on last line):

Visual Basic:
	Dim KeyID As Integer
	KeyID = CType(e.Item.FindControl("UniqueID"), Label).Text
	Dim foundRow As DataRow
	foundRow = dtTeamPlayers.Rows.Find("KeyID")

Could this be something to do with the auto-increment feature?
 
Last edited by a moderator:
Back
Top