I have a private, Serializable custom object class called results within my namespace which I use to store the results of a file upload/server push:
namespace DataUploadTool
{
enum errors {none, format, data, type, unk};
public partial class uploader : System.Web.UI.Page
{
private results res;
[Serializable]
private class results
{
public string errLogPath { get; set; }
public string fileName { get; set; }
public int errorType { get; set; }
public int rowsImported { get; set; }
public DateTime startTime { get; set; }
public DateTime endTime { get; set; }
}
...
}
I set the members of the object in the standard way in my code, i.e.
res.fileName = fileUpload.FileName;
etc.
I add the object to the ViewState:
void Page_PreRender(object sender, EventArgs e)
{
ViewState.Add("resultsLog", res);
}
And I attempt to retrieve it like so:
protected void Page_Load(object sender, EventArgs e)
{
res = new results();
if (IsPostBack)
{
if (ViewState["resultsLog"] != null)
{
results test;
test = (results)ViewState["resultslog"];
error.Text = test.rowsImported.ToString();
}
else // Do things
}
}
The problem is I keep getting nullReferenceException on the line error.Text = test.rowsImported.ToString();
.
The built in data visulaizer tool in Visual Studio tells me that test is null after the line where it is retrieved from the ViewState, which doesn't make any sense at all because it was determined not null by the if statement! I am at a complete loss on how or why this is happening.
Any help is appreciated!
I figured out what was going wrong.
The PostBack occurs before the ViewState save because my database populating function was called before that.
If you're having the problem where your ViewState/Session variable is null the first postback but proceeding postbacks contain the variable from the previous request, that is what is happening.
Clarification: Let's say after every database insertion (occuring on the button_onClick function) I want to display the result of the inserting in a label. The following actions in order exemplify this:
So as you see the updated variable is visible to the following postback.
Essentially, I didn't need to use ViewState or Session at all. I could operate on the object data at the end of the onClick function because at that point the postback had already occurred.
TL;DR: If you're having problems with ViewState or Session variables/objects not persisting, or are experiencing odd "one-off" logic errors, then add breakpoints at each line of code involving:
- View/Session state setting/getting
- Function declarations which call these getters/setters
- Any function which accesses database data (reading/writing)
By following these breadcrumbs, you'll very quickly recognize the order in which the page life cycle is progressing.