Object reference not set to an instance of an object. - Visual Basic (Web)


So, I'm having a slight problem with my code.

I was working on a small school project (recreation of book library) and encountered a problem which I cannot get a grasp of.

So, the user can search for a list of books, and after the list is populated (via DataList control), a small button "Book now" (Reserve) appears which user can click and reserve his book.

This is the code for the DataList control that resides in "Search.aspx"

<asp:DataList ID="DataList1" runat="server" DataKeyField="knjigaId" DataSourceID="SearchSqlDataSource" CssClass="searchControl">
                <div class="pictureOfFoundBook">
                    <asp:Image ID="pictureOfFoundBook_imageLink" runat="server" ImageUrl='<%#"~/GetImage.aspx?knjigaId=" & Eval("knjigaId") & "&img=naslovnica" %>' />
                <div class="descriptionOfFoundBook">
                    Naziv: <asp:Label ID="Label1" runat="server" Text='<%# Eval("naziv") %>' /><br />
                    Godina izdanja: <asp:Label ID="Label2" runat="server" Text='<%# Eval("godinaIzdanja") %>' /><br />
                    Broj stranica : <asp:Label ID="brojStranicaLabel" runat="server" Text='<%# Eval("brojStranica") %>' /><br />
                    Izdavač: <asp:Label ID="NazivIzdavacaLabel" runat="server" Text='<%# Eval("NazivIzdavaca") %>' /><br />
                    Vrsta tiskovine : <asp:Label ID="NazivVrsteTiskovineLabel" runat="server" Text='<%# Eval("NazivVrsteTiskovine") %>' /><br />
                    Kategorija: <asp:Label ID="NazivKategorijeLabel" runat="server" Text='<%# Eval("NazivKategorije") %>' /><br /><br />
                    <asp:HyperLink ID="foundBookEditHL_adminOnly" runat="server" NavigateUrl='<%# "~/admin/knjigeEdit.aspx?knjigaId=" & Eval("knjigaId") %>'>Uredi knjigu</asp:HyperLink><br />
                    <asp:Button ID="rezervacijeButton" runat="server" Text="Rezerviraj" OnClick="rezervacijaClick" CommandArgument='<%# Eval("knjigaId") %>'/><br />
                    <asp:Label ID="rezStatusLabel" runat="server"></asp:Label>
                    <asp:PlaceHolder ID="rezStatusPlaceholder" runat="server"></asp:PlaceHolder>
                <hr />

I've set the DataList1 control as a Friend sub so I can access the controls in it from another sub;

Friend Sub DataList1_ItemCreated(sender As Object, e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemCreated
    End Sub

I was trying to do the following; on the click of a button "rezervacijeButton", a function "rezervacijaClick" runs, which populates the table in the database.

Protected Sub rezervacijaClick(sender As Object, e As System.EventArgs)
            Dim Conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ToString)
            Dim cmd As New System.Data.SqlClient.SqlCommand
            Dim sql As New StringBuilder
            Dim rezstatus As Label = DataList1.FindControl("rezStatusLabel")

            sql.Append("INSERT INTO rezervacije(UserName, knjigaId) VALUES (@UserName, @knjigaId)")

            Dim buttonsender As Button = sender
            cmd.Parameters.AddWithValue("UserName", User.Identity.Name)
            cmd.Parameters.AddWithValue("knjigaId", buttonsender.CommandArgument)

            cmd.CommandText = sql.ToString
            cmd.Connection = Conn

            buttonsender.Visible = False
            rezstatus.Text = "aaa"

            '    rezstatus.Text = "testing..."
            'Catch ex As Exception
            '    exlabel.Text = "POGREŠKA"
            '    exlabel.ForeColor = Drawing.Color.Red
        End Sub

The next thing I wanted to do in the function "rezervacijaClick" was to set the text value of the Label (with ID "rezStatusLabel", which resides inside the DataList1 control) to "SOME TEXT" after the "Reserve" button is clicked.

But after the button click, I get the following error :

 Object reference not set to an instance of an object.
Line 21:
Line 22:         buttonsender.Visible = False
Line 23:         rezstatus.Text = "aaa"
Line 24:
Line 25:         'Try

Your rezstatus object is Nothing (null).

This is happening because you aren't looking in the right place for your label.

Each record of data you bind to the DataList will create a new hierarchy of controls, containers that hold the other controls you have defined in your ItemTemplate.

The immediate descendants of DataList1 will be a collection of DataListItem objects and then you will have your controls inside those.

Since we don't know for sure (unless you know you are only binding one record to the DataList) which DataListItem the desired label will be in, we simply walk backwards up the control tree and find the label from there.

Because you are responding to a button click event in your rezervacijaClick method, the parameter sender will be of type Button and will come from rezervacijeButton, so we can use that information to find your label:

Dim clickedButton As Button = CType(sender, Button) 'convert the sender parameter to the correct type: Button
Dim buttonParent As Control = clickedButton.Parent 'get a reference to the button's parent control
Dim rezstatus As Label = CType(buttonParent.FindControl(""), Label) 'find the label by ID and convert it to a Label as the return type of FindControl is Control