0

This is a continuation of this thread with how to build a DetailsView button that will check all the boxes in a given form. I attempted to get assistance within the previous thread but there were no responses thus the new thread.

As of right now, the checkbox button works with no issues but when I go to click the 'Save' button, an error message appears in the cs file at this line:

                TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
                if (tb != null)
                {
                    table.Rows[0][j] = tb.Text;
                }

With the error:

System.NullReferenceException: Object reference not set to an instance of an object.

I'm stumped as to what I'm doing wrong here. I'm thinking I don't know how the process fully works behind the scenes. I've been pouring over MSDN documentation to see if I can get a better explanation on how to theoretically save this to the database correctly but haven't been able to find the proper documentation to assist.

The SQL Code is solid and was working with no issues before I added the checkbox button to the code.

Form Code:

(Note some cosmetic code for the details view has been omitted)


<%@ Page Title="Test Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="form2.aspx.cs" Inherits="form2" %>   
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:DetailsView ID="DetailsView" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None">
<AlternatingRowStyle BackColor="White" />
<insert asp cosmetic gobbledy gook here>
<Fields>
    <asp:BoundField DataField="Field_1" HeaderText="Ticket Number" SortExpression="Field_1" />
    <asp:BoundField DataField="Field 2" HeaderText="Field 2" SortExpression="Field_2" />
    <asp:BoundField DataField="Field_3" HeaderText="Field 3" SortExpression="Field_3" />
    <asp:BoundField DataField="Field_4" HeaderText="Field 4" SortExpression="Field_4" />
    <asp:BoundField DataField="Field_5" HeaderText="Field 5" SortExpression="Field_5" />
    <asp:BoundField DataField="Field_6" HeaderText="Field 6" SortExpression="Field_6" />
    <asp:BoundField DataField="Field_7" HeaderText="Field 7" SortExpression="Field_7" />
    <asp:BoundField DataField="Field_8" HeaderText="Field 8" SortExpression="Field_8" />
    <asp:BoundField DataField="Field_9" HeaderText="Field 9" SortExpression="Field_9" />
    <asp:BoundField DataField="Field_10" HeaderText="Field 10" SortExpression="Field_10" />
    <asp:CheckBoxField DataField="Check_Box_1" HeaderText="Check Box 1" SortExpression="Check_Box_1" />
    <asp:CheckBoxField DataField="Check_Box_2" HeaderText="Check Box 2" SortExpression="Check_Box_2" />
    <asp:CheckBoxField DataField="Check_Box_3" HeaderText="Check Box 3" SortExpression="Check_Box_3" />
    <asp:CheckBoxField DataField="Check_Box_4" HeaderText="Check Box 4" SortExpression="Check_Box_4" />
    <asp:CheckBoxField DataField="Check_Box_5" HeaderText="Check Box 5" SortExpression="Check_Box_5" />
    <asp:CheckBoxField DataField="Check_Box_6" HeaderText="Check Box 6" SortExpression="Check_Box_6" />
    <asp:CheckBoxField DataField="Check_Box_7" HeaderText="Check Box 7" SortExpression="Check_Box_7" />
    <asp:CheckBoxField DataField="Check_Box_8" HeaderText="Check Box 8" SortExpression="Check_Box_8" />
    <asp:CheckBoxField DataField="Check_Box_9" HeaderText="Check Box 9" SortExpression="Check_Box_9" />
    <asp:CheckBoxField DataField="Check_Box_10" HeaderText="Check Box 10" SortExpression="Check_Box_10" />
    <asp:CheckBoxField DataField="Check_Box_11" HeaderText="Check Box 11" SortExpression="Check_Box_11" />
    <asp:CheckBoxField DataField="Check_Box_12" HeaderText="Check Box 12" SortExpression="Check_Box_12" />
    <asp:CheckBoxField DataField="Check_Box_13" HeaderText="Check Box 13" SortExpression="Check_Box_13" />
    <asp:CheckBoxField DataField="Check_Box_14" HeaderText="Check Box 14" SortExpression="Check_Box_14" />
    <asp:CheckBoxField DataField="Check_Box_15" HeaderText="Check Box 15" SortExpression="Check_Box_15" />
    <asp:CheckBoxField DataField="Check_Box_16" HeaderText="Check Box 16" SortExpression="Check_Box_16" />
    <asp:CheckBoxField DataField="Check_Box_17" HeaderText="Check Box 17" SortExpression="Check_Box_17" />
    <asp:CheckBoxField DataField="Check_Box_18" HeaderText="Check Box 18" SortExpression="Check_Box_18" />
    <asp:CheckBoxField DataField="Check_Box_19" HeaderText="Check Box 19" SortExpression="Check_Box_19" />


    <asp:ButtonField ButtonType="Button" CommandName="btnSelectAll" Text="Select/Check All Servers" >


    <asp:BoundField DataField="Field_11" HeaderText="Field 11" SortExpression="Field_11" />
    <asp:BoundField DataField="Field_12" HeaderText="Field 12" SortExpression="Field_12" />
    <asp:BoundField DataField="Field_13" HeaderText="Field 13" SortExpression="Field_13" />


    <asp:ButtonField ButtonType="Button" CommandName="btnCancel" Text="Cancel" />
    <asp:ButtonField ButtonType="Button" CommandName="btnSave" Text="Save" />

    <asp:CommandField ButtonType="Button" NewText="CreateRecord" ShowInsertButton="True" />
</Fields>
<more asp non essential cosmetic gobbledy gook>

    </asp:DetailsView>
    <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:test_form_connect %>" runat="server" InsertCommand="INSERT INTO [test].[detailsview_test_form] ([Field_1], [Field_2], [Field_3], [Field_4], [Field_5], [Field_6], [Field_7], [Field_8], [Field_9], [Field_10], [Check_Box_1], [Check_Box_2], [Check_Box_3], [Check_Box_4], [Check_Box_5], [Check_Box_6], [Check_Box_7], [Check_Box_8], [Check_Box_9], [Check_Box_10], [Check_Box_11], [Check_Box_12], [Check_Box_13], [Check_Box_14], [Check_Box_15], [Check_Box_16], [Check_Box_17], [Check_Box_18], [Check_Box_19], [Field_11], [Field_12], [Field_13]) VALUES (@Field_1, @Field_2, @Field_3, @Field_4, @Field_5, @Field_6, @Field_7, @Field_8, @Field_9, @Field_10, @Check_Box_1, @Check_Box_2, @Check_Box_3, @Check_Box_4, @Check_Box_5, @Check_Box_6, @Check_Box_7, @Check_Box_8, @Check_Box_9, @Check_Box_10, @Check_Box_11, @Check_Box_12, @Check_Box_13, @Check_Box_14, @Check_Box_15, @Check_Box_16, @Check_Box_17, @Check_Box_18, @Check_Box_19, @Field_11, @Field_12, @Field_13) ">

    <InsertParameters>
<asp:Parameter Name="Field_1" />
<asp:Parameter Name="Field_2" />
<asp:Parameter Name="Field_3" />
<asp:Parameter Name="Field_4" />
<asp:Parameter Name="Field_5" />
<asp:Parameter Name="Field_6" />
<asp:Parameter Name="Field_7" />
<asp:Parameter Name="Field_8" />
<asp:Parameter Name="Field_9" />
<asp:Parameter Name="Field_10" />
<asp:Parameter Name="Check_Box_1" />
<asp:Parameter Name="Check_Box_2" />
<asp:Parameter Name="Check_Box_3" />
<asp:Parameter Name="Check_Box_4" />
<asp:Parameter Name="Check_Box_5" />
<asp:Parameter Name="Check_Box_6" />
<asp:Parameter Name="Check_Box_7" />
<asp:Parameter Name="Check_Box_8" />
<asp:Parameter Name="Check_Box_9" />
<asp:Parameter Name="Check_Box_10" />
<asp:Parameter Name="Check_Box_11" />
<asp:Parameter Name="Check_Box_12" />
<asp:Parameter Name="Check_Box_13" />
<asp:Parameter Name="Check_Box_14" />
<asp:Parameter Name="Check_Box_15" />
<asp:Parameter Name="Check_Box_16" />
<asp:Parameter Name="Check_Box_17" />
<asp:Parameter Name="Check_Box_18" />
<asp:Parameter Name="Check_Box_19" />
<asp:Parameter Name="Field_11" />
<asp:Parameter Name="Field_12" />
<asp:Parameter Name="Field_13" />

        </InsertParameters>
        </asp:SqlDataSource>


</asp:Content>

Code Behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;

public partial class checkbox_dev : System.Web.UI.Page
{
DataTable m_table = null;

public DataTable table

{
    get
    {
        if (ViewState["m_table"] != null)
            return (DataTable)ViewState["m_table"];
        else
            return null;
    }
    set
    {
        ViewState["m_table"] = value;
    }
}

public static T FindControl<T>(ControlCollection controls)
{
    for (int i = 0; i < controls.Count; i++)
    {
        if (controls[i] is T)
            return (T)(object)controls[i];
    }

    return default(T);
}

protected void Page_Load(object sender, EventArgs e)
//private static DataTable GetData(string sqlCommand)
{
    string connectionString = GetConnectionString();
    SqlConnection connection = new SqlConnection(connectionString);
}

static private string GetConnectionString()
{
    return "(insert SQL Server connection Stringhere)";
}



protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
{
    if (e.CommandName == "btnSelectAll")
    {
        foreach (DetailsViewRow row in DetailsView1.Rows)
        {
            for (int i = 0; i < row.Cells.Count; i++)
            {
                CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
                if (cb != null)
                {
                    cb.Checked = true;
                }
            }
        }
    }
    if (e.CommandName == "btnSave")
    {
        int j = 0;
        foreach (DetailsViewRow row in DetailsView1.Rows)
        {
            for (int i = 0; i < row.Cells.Count; i++)
            {
                TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
                if (tb != null)
                {
                    table.Rows[0][j] = tb.Text;
                }

                CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
                if (cb != null)
                {
                    table.Rows[0][j] = cb.Checked;
                }
            }
            j++;
        }

        DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
        DetailsView1.DataSource = table;
        DetailsView1.DataBind();
    }
    if (e.CommandName == "btnEdit")
    {
        DetailsView1.ChangeMode(DetailsViewMode.Edit);
        DetailsView1.DataSource = table;
        DetailsView1.DataBind();
    }
    if (e.CommandName == "btnCancel")
    {
        DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
        DetailsView1.DataSource = table;
        DetailsView1.DataBind();
    }
}

}
Community
  • 1
  • 1
Techie Joe
  • 847
  • 2
  • 14
  • 32
  • Are you certain 'table' is not returning a null? Your get method has the potential to return null, I would put a break point on it and see what it is returning. – JuStDaN Oct 09 '13 at 01:33
  • In this line: "TextBox tb = FindControl(row.Cells[i].Controls);" Add a breakpoint, in the immediate window, type: "row.Cells[i].Controls", if it's null, type "row" to see if it's null – User2012384 Oct 09 '13 at 01:57
  • 1
    Almost all cases of `NullReferenceException` are the same. Please see "[What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)" for some hints. – John Saunders Oct 13 '13 at 02:34

1 Answers1

0

I think the biggest issue that pops out to me is the assumption your code is making within your syntax, row.Cells[i].Controls. You should be checking to make sure the cell has a 'Controls' collection.

Looking at this block of code, my initial sensors are going crazy.

if (e.CommandName == "btnSave")
{
    int j = 0;
    foreach (DetailsViewRow row in DetailsView1.Rows)
    {
        for (int i = 0; i < row.Cells.Count; i++)
        {
            TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
            if (tb != null)
            {
                table.Rows[0][j] = tb.Text;
            }

            CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
            if (cb != null)
            {
                table.Rows[0][j] = cb.Checked;
            }
        }
        j++;
    }

What you are doing above, is essentially initializing an variable of type, 'int' to 0 (int j = 0;), but then you increment it with no regard to the Column collection index you are attempting to access later in your code above, table.Rows[0][j] = cb.Checked; for each row of 'DetailsView1.Rows'.

So basically what you're doing is incrementing by 1 for each row in DetailsView1.Rows, and attempting to access the 'Columns' of your DataTable by that index. However, what if a column doesn't exist at that index?

One thing I would suggest to fix the problem in the interim is to check for the existence of the cell in the "Cells" collection before using it. Like this...

if (table.Rows[0][j] != null)
{
    table.Rows[0][j] = tb.Text;
}

This is just a band aid fix and should not be used long term as the fundamental issue of possibly iterating past the bounds of the collection is not really acceptable practice. I'd take some time and analyze your methodologies and refactor. Yes, it may make sense to you that the cells should all exist, being that the rows of your detail view are less than the cells of your DataTable, but it is still not good practice and could potentially be a reason for your error here.

Justin Russo
  • 2,214
  • 1
  • 22
  • 26
  • Working on this now but I'm running into challenges with my debugger not functioning in SSL. Gonna need a day. – Techie Joe Oct 09 '13 at 20:07
  • Can you not run locally in the VS IIS light environment? – Justin Russo Oct 10 '13 at 00:15
  • No, I'm forcing SSL on this website and it's choking right now. I'm configuring VS to leverage the cert. – Techie Joe Oct 10 '13 at 16:12
  • Ok got the issues resolved with the debugger. The error from the debugger is that "The Field 'checkbox_dev.m_table' is assigned but its value is never used. Right at the 'DataTable m_table = null;' line. – Techie Joe Oct 22 '13 at 20:41
  • For now, you'll want to comment out this line, 'DataTable m_table = null;', unless you don't need m_table. Then you can just delete the whole line. This way you can get passed that exception, so you can deal with the other exception. – Justin Russo Oct 22 '13 at 23:30