csetzkorn
asked on
asp.net c# System.NullReferenceException
My code throws a System.NullReferenceExcept ion when I click the add_category button. However, the dataset that is bound to my datagrid should be initialised (see method Page_Load). When the site is loaded the first time the BindGrid() method should be invoked and initialize the dataset object.
Any suggestion?
Many thanks.
Christian
I have added the asp.net and the c# code behind file below.
<%@ Page language="c#" Codebehind="variable_propo sal_form.a spx.cs" AutoEventWireup="false" Inherits="geoconda.Members Only.varia ble_propos al_form" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>variable_proposal_f orm</title >
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScri pt" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout ">
<form id="variable_proposal_form " method="post" runat="server">
<asp:textbox id="cat_value" style="Z-INDEX: 101; LEFT: 312px; POSITION: absolute; TOP: 152px"
runat="server"></asp:textb ox>
<asp:DataGrid id="categories_datagrid" runat="server" style="Z-INDEX: 102; LEFT: 40px; POSITION: absolute; TOP: 136px"></asp:DataGrid>
<asp:textbox id="cat_value_label" runat="server" style="Z-INDEX: 103; LEFT: 320px; POSITION: absolute; TOP: 288px"></asp:textbox>
<asp:label id="value" runat="server" Font-Bold="True" style="Z-INDEX: 104; LEFT: 336px; POSITION: absolute; TOP: 120px">Value:
</asp:label>
<asp:label id="value_label" runat="server" Font-Bold="True" style="Z-INDEX: 105; LEFT: 352px; POSITION: absolute; TOP: 232px">Value Label:
</asp:label>
<asp:button id="add_category" runat="server" Text="<" style="Z-INDEX: 106; LEFT: 264px; POSITION: absolute; TOP: 168px"></asp:button>
<asp:button id="remove_category" runat="server" Text=">" style="Z-INDEX: 107; LEFT: 272px; POSITION: absolute; TOP: 232px"></asp:button>
</form>
</body>
</HTML>
code behind file:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls ;
namespace geoconda.MembersOnly
{
/// <summary>
/// Summary description for variable_proposal_form.
/// </summary>
public class variable_proposal_form : System.Web.UI.Page
{
protected System.Web.UI.WebControls. TextBox cat_value;
protected System.Web.UI.WebControls. DataGrid categories_datagrid;
protected System.Web.UI.WebControls. TextBox cat_value_label;
protected System.Web.UI.WebControls. Label value;
protected System.Web.UI.WebControls. Label value_label;
protected System.Web.UI.WebControls. Button add_category;
protected System.Web.UI.WebControls. Button remove_category;
protected DataSet dataSet;
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!IsPostBack)
{
BindGrid();
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.categories_datagrid.S electedInd exChanged += new System.EventHandler(this.c ategories_ datagrid_S electedInd exChanged) ;
this.add_category.Click += new System.EventHandler(this.a dd_categor y_Click);
this.remove_category.Click += new System.EventHandler(this.r emove_cate gory_Click );
this.Load += new System.EventHandler(this.P age_Load);
}
#endregion
private void BindGrid()
{
dataSet = new DataSet();
DataTable categories = new DataTable( "categories" );
categories.Columns.Add( new DataColumn( "value", typeof(string) ) );
categories.Columns.Add( new DataColumn( "value_label", typeof(string) ) );
dataSet.Tables.Add( categories );
categories_datagrid.DataSo urce = dataSet.Tables[ "categories" ];
categories_datagrid.DataBi nd();
}
private void categories_datagrid_Select edIndexCha nged(objec t sender, System.EventArgs e)
{
}
private void add_category_Click(object sender, System.EventArgs e)
{
DataRow newRow;
dataSet.Tables[ "categories" ].NewRow();
newRow = dataSet.Tables[ "categories" ].NewRow();
newRow["value"] = cat_value.Text;
newRow["value_label"] = cat_value_label.Text;
dataSet.Tables[ "categories" ].Rows.Add( newRow );
categories_datagrid.DataBi nd();
cat_value.Text = "";
cat_value_label.Text = "";
}
private void remove_category_Click(obje ct sender, System.EventArgs e)
{
}
}
}
Any suggestion?
Many thanks.
Christian
I have added the asp.net and the c# code behind file below.
<%@ Page language="c#" Codebehind="variable_propo
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>variable_proposal_f
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScri
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout
<form id="variable_proposal_form
<asp:textbox id="cat_value" style="Z-INDEX: 101; LEFT: 312px; POSITION: absolute; TOP: 152px"
runat="server"></asp:textb
<asp:DataGrid id="categories_datagrid" runat="server" style="Z-INDEX: 102; LEFT: 40px; POSITION: absolute; TOP: 136px"></asp:DataGrid>
<asp:textbox id="cat_value_label" runat="server" style="Z-INDEX: 103; LEFT: 320px; POSITION: absolute; TOP: 288px"></asp:textbox>
<asp:label id="value" runat="server" Font-Bold="True" style="Z-INDEX: 104; LEFT: 336px; POSITION: absolute; TOP: 120px">Value:
</asp:label>
<asp:label id="value_label" runat="server" Font-Bold="True" style="Z-INDEX: 105; LEFT: 352px; POSITION: absolute; TOP: 232px">Value Label:
</asp:label>
<asp:button id="add_category" runat="server" Text="<" style="Z-INDEX: 106; LEFT: 264px; POSITION: absolute; TOP: 168px"></asp:button>
<asp:button id="remove_category" runat="server" Text=">" style="Z-INDEX: 107; LEFT: 272px; POSITION: absolute; TOP: 232px"></asp:button>
</form>
</body>
</HTML>
code behind file:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls
namespace geoconda.MembersOnly
{
/// <summary>
/// Summary description for variable_proposal_form.
/// </summary>
public class variable_proposal_form : System.Web.UI.Page
{
protected System.Web.UI.WebControls.
protected System.Web.UI.WebControls.
protected System.Web.UI.WebControls.
protected System.Web.UI.WebControls.
protected System.Web.UI.WebControls.
protected System.Web.UI.WebControls.
protected System.Web.UI.WebControls.
protected DataSet dataSet;
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!IsPostBack)
{
BindGrid();
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.categories_datagrid.S
this.add_category.Click += new System.EventHandler(this.a
this.remove_category.Click
this.Load += new System.EventHandler(this.P
}
#endregion
private void BindGrid()
{
dataSet = new DataSet();
DataTable categories = new DataTable( "categories" );
categories.Columns.Add( new DataColumn( "value", typeof(string) ) );
categories.Columns.Add( new DataColumn( "value_label", typeof(string) ) );
dataSet.Tables.Add( categories );
categories_datagrid.DataSo
categories_datagrid.DataBi
}
private void categories_datagrid_Select
{
}
private void add_category_Click(object sender, System.EventArgs e)
{
DataRow newRow;
dataSet.Tables[ "categories" ].NewRow();
newRow = dataSet.Tables[ "categories" ].NewRow();
newRow["value"] = cat_value.Text;
newRow["value_label"] = cat_value_label.Text;
dataSet.Tables[ "categories" ].Rows.Add( newRow );
categories_datagrid.DataBi
cat_value.Text = "";
cat_value_label.Text = "";
}
private void remove_category_Click(obje
{
}
}
}
ASKER
Thanks for your reply.
Where would I have to add the line:
ViewState.Add("somename", dataSet)
Could you please elaborate point three a bit more?
Thanks!
Where would I have to add the line:
ViewState.Add("somename", dataSet)
Could you please elaborate point three a bit more?
Thanks!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
1. ser makes a request to a.aspx
2. The class for a.aspx is instantiated.
3. All the event handlers are called (including Page_Load(). This is where your dataset is populated.
4. All ASP.Net controls write the viewstate to a state property bag. This is rendered to the page as encrypted string. (that is whay you see a hidden field named __VIEWSTATE in any aspx page source)
4. ASP.Net calls render methods on the page controls to extract the HTML (I will skip some detailed steps here).
5. Class is then DESTROYED and HTML is rendered.
6. There is a post back.
7. ASP.Net instantiates the class for a.aspx for the SECOND time. (Hence your dataset value will be null here).
8. All controls read values from the viewstate.
9. All control events are called (i.e. Page_Load)
10. The processing continues as before.
So in this cycle, the code behind class actually gets instantiated number of times (= 1 + number of post backs). Now, controls save their properties in the viewstate and retrieve it in the subsequent call. (Datasource property of the datagrid control does not get saved in the viewstate by default).
So to get around your problem you have a number of options:
1. Save the dataset in session (problem is, the web server will be overloaded)
2. Save the dataset in the viewstate (page wil be very heavy). You can use the code
ViewState.Add("somename", dataSet)
in the BindGrid. Then modify your page load as
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!IsPostBack)
{
BindGrid();
}
else
{
dataSet = (DataSet)(ViewState["somen
}
3. Iterate through the datagrid object item collection to get all data. Form a dataset from these data. Add a row manually to the dataset created. Then bind this dataset. This requires some coding. But it should provide good performance and less load on the server (and the page size will not go up!).