I've solved the problem (explanation below) but I'm trying to figure out why the stack trace is giving me the wrong line.
Overview: This is a Repeater control that allows a professor to mark an exam, one question at a time while still being able to view an entire exam.
Basic Idea (pseudo.aspx):
<asp:repeater>
<ItemTemplate>
<fields/>
<textbox id="grade">
<asp:LinkButton ID="UpdateButton" runat="server" Text="Update" OnClick="OnUpdate" />
</ItemTemplate>
</asp:repeater>
The user is supposed to enter a grade, and the question mark is updated in the database in the OnClick event, and the entire page is databound again.
Code:
protected void OnUpdate(object sender, EventArgs e)
{ // I broke this down line by line trying to trace the error.
LinkButton button = (LinkButton)sender; //Object Not set exception here!!!
object o = button.Parent;
RepeaterItem item = o as RepeaterItem;
int StudentID = int.Parse((item.FindControl("StudentKeyLabel1") as HiddenField).Value);
string ExamID = (item.FindControl("ExamIDLabel1") as HiddenField).Value.Trim();
int QuestionID = int.Parse((item.FindControl("QuestionIDLabel1") as HiddenField).Value);
int Grade;
try
{
Grade = int.Parse((item.FindControl("GradeTextBox") as TextBox).Text);
// Update DB
}
catch (FormatException)
{ // Message to user - bad or missing grade }
//Custom Databind
}
I had changed the fields in the .aspx from labels to hidden fields in the aspx, but forgot to change them in the .aspx.cs file -- This was the actual cause of the error.
However, the stack trace (customerrors="Off") showed the Object reference not set to type Object as occurring at this line:
LinkButton button = (LinkButton)sender; //Object Not set error here!!!
but the actual error was several lines below.
My oversight took a long time to fix because of this. You can see that I broke down the retrieval of the RepeaterItem line by line, and put a throw new Exception(xxx.GetType().ToString()
to check for reference validity after each line trying to figure it out. The funny thing is, that the original error didn't appear when there was a manual throw lower down.
Why was the stack trace showing the exception as coming from the wrong spot in the code?