Why do I keep getting a null (or other) error with gridview and DataRowView?

  • Thread starter Thread starter needin4mation
  • Start date Start date
N

needin4mation

In this code:

protected void GridView1_RowCreated(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;

// Retrieve the value for the current row.
string idValue = rowView["id"].ToString();


//do more stuff


}
}

This code works when I run my gridview, but as soon as I try and go to
the second page I get an error in Visual Studio that says:

Use the "new" keyword to create and object reference

Check to determine if the object is null before calling the method

Here is what is copied to the clipboard from VS:

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="App_Web_fiaeux3t"
StackTrace:
at test.GridView1_RowCreated(Object sender, GridViewRowEventArgs
e) in c:\websites\BootStore\test.aspx.cs:line 27
at
System.Web.UI.WebControls.GridView.OnRowCreated(GridViewRowEventArgs e)
at System.Web.UI.WebControls.GridView.CreateRow(Int32 rowIndex,
Int32 dataSourceIndex, DataControlRowType rowType, DataControlRowState
rowState, Boolean dataBind, Object dataItem, DataControlField[] fields,
TableRowCollection rows, PagedDataSource pagedDataSource)
at
System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable
dataSource, Boolean dataBinding)
at
System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
at System.Web.UI.Adapters.ControlAdapter.CreateChildControls()
at System.Web.UI.Control.EnsureChildControls()
at
System.Web.UI.WebControls.CompositeDataBoundControl.get_Controls()
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Page.LoadAllState()
at System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


I know there is data in the second page and it has an id value. I have
run it without the statement above to verify it. Just blows up on each
hit to anything but the first page.

Thank you for any help.
 
The DataItem property of GridViewRow is set only after data-binding.
If use classic data-binding pattern under !IsPostBack condition, then the
DataItem is null during postbacks!!!

You have to read the values form the Cells (not DataItem), if you need it on
every request.
(DataItem should be used "only" in RowDataBound event.)

Robert Haken [MVP ASP/ASP.NET]
HAVIT, s.r.o., www.havit.cz
http://knowledge-base.havit.cz


In this code:

protected void GridView1_RowCreated(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;

// Retrieve the value for the current row.
string idValue = rowView["id"].ToString();


//do more stuff


}
}

This code works when I run my gridview, but as soon as I try and go to
the second page I get an error in Visual Studio that says:

Use the "new" keyword to create and object reference

Check to determine if the object is null before calling the method

Here is what is copied to the clipboard from VS:

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="App_Web_fiaeux3t"
StackTrace:
at test.GridView1_RowCreated(Object sender, GridViewRowEventArgs
e) in c:\websites\BootStore\test.aspx.cs:line 27
at
System.Web.UI.WebControls.GridView.OnRowCreated(GridViewRowEventArgs e)
at System.Web.UI.WebControls.GridView.CreateRow(Int32 rowIndex,
Int32 dataSourceIndex, DataControlRowType rowType, DataControlRowState
rowState, Boolean dataBind, Object dataItem, DataControlField[] fields,
TableRowCollection rows, PagedDataSource pagedDataSource)
at
System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable
dataSource, Boolean dataBinding)
at
System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
at System.Web.UI.Adapters.ControlAdapter.CreateChildControls()
at System.Web.UI.Control.EnsureChildControls()
at
System.Web.UI.WebControls.CompositeDataBoundControl.get_Controls()
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Page.LoadAllState()
at System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


I know there is data in the second page and it has an id value. I have
run it without the statement above to verify it. Just blows up on each
hit to anything but the first page.

Thank you for any help.
 
I suspect that it is this line:

DataRowView rowView = (DataRowView)e.Row.DataItem;

As the exception message states, you should check the item for null before
assigning it.

if (e.Row.DataItem != null)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;
}

On a different note:

I'm not 100% sure on this, but it doesn't seem like you should have to check
to see if e.Row.RowType = == DataControlRowType.DataRow since e.Row
represents the GridView's row in the first place. Of course e.Row.RowType
will equal a DataControlRowType.DataRow, right?




In this code:

protected void GridView1_RowCreated(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;

// Retrieve the value for the current row.
string idValue = rowView["id"].ToString();


//do more stuff


}
}

This code works when I run my gridview, but as soon as I try and go to
the second page I get an error in Visual Studio that says:

Use the "new" keyword to create and object reference

Check to determine if the object is null before calling the method

Here is what is copied to the clipboard from VS:

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="App_Web_fiaeux3t"
StackTrace:
at test.GridView1_RowCreated(Object sender, GridViewRowEventArgs
e) in c:\websites\BootStore\test.aspx.cs:line 27
at
System.Web.UI.WebControls.GridView.OnRowCreated(GridViewRowEventArgs e)
at System.Web.UI.WebControls.GridView.CreateRow(Int32 rowIndex,
Int32 dataSourceIndex, DataControlRowType rowType, DataControlRowState
rowState, Boolean dataBind, Object dataItem, DataControlField[] fields,
TableRowCollection rows, PagedDataSource pagedDataSource)
at
System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable
dataSource, Boolean dataBinding)
at
System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
at System.Web.UI.Adapters.ControlAdapter.CreateChildControls()
at System.Web.UI.Control.EnsureChildControls()
at
System.Web.UI.WebControls.CompositeDataBoundControl.get_Controls()
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Page.LoadAllState()
at System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


I know there is data in the second page and it has an id value. I have
run it without the statement above to verify it. Just blows up on each
hit to anything but the first page.

Thank you for any help.
 
Moving everything to the RowDataBound event solves it.
I suspect that it is this line:

DataRowView rowView = (DataRowView)e.Row.DataItem;

As the exception message states, you should check the item for null before
assigning it.

if (e.Row.DataItem != null)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;
}

On a different note:

I'm not 100% sure on this, but it doesn't seem like you should have to check
to see if e.Row.RowType = == DataControlRowType.DataRow since e.Row
represents the GridView's row in the first place. Of course e.Row.RowType
will equal a DataControlRowType.DataRow, right?




In this code:

protected void GridView1_RowCreated(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;

// Retrieve the value for the current row.
string idValue = rowView["id"].ToString();


//do more stuff


}
}

This code works when I run my gridview, but as soon as I try and go to
the second page I get an error in Visual Studio that says:

Use the "new" keyword to create and object reference

Check to determine if the object is null before calling the method

Here is what is copied to the clipboard from VS:

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="App_Web_fiaeux3t"
StackTrace:
at test.GridView1_RowCreated(Object sender, GridViewRowEventArgs
e) in c:\websites\BootStore\test.aspx.cs:line 27
at
System.Web.UI.WebControls.GridView.OnRowCreated(GridViewRowEventArgs e)
at System.Web.UI.WebControls.GridView.CreateRow(Int32 rowIndex,
Int32 dataSourceIndex, DataControlRowType rowType, DataControlRowState
rowState, Boolean dataBind, Object dataItem, DataControlField[] fields,
TableRowCollection rows, PagedDataSource pagedDataSource)
at
System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable
dataSource, Boolean dataBinding)
at
System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
at System.Web.UI.Adapters.ControlAdapter.CreateChildControls()
at System.Web.UI.Control.EnsureChildControls()
at
System.Web.UI.WebControls.CompositeDataBoundControl.get_Controls()
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList
childState)
at System.Web.UI.Control.LoadViewStateRecursive(Object
savedState)
at System.Web.UI.Page.LoadAllState()
at System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


I know there is data in the second page and it has an id value. I have
run it without the statement above to verify it. Just blows up on each
hit to anything but the first page.

Thank you for any help.
 
Back
Top