Link to home
Start Free TrialLog in
Avatar of goodmanro
goodmanroFlag for United States of America

asked on

FileUpload Control and NullReferenceException

I have this in my .ASPX page:

                     <asp:FileUpLoad id="ImageURLTB" AlternateText="You cannot upload files" runat="server" />
                     <asp:Button id="UploadImage" Text="Upload" OnClick="UploadImage_Click" runat="server" />

And this in my code-behind:

    Sub UploadImage_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim ImageURLTB As FileUpload = Gridview1.FindControl("ImageURLTB")

        If ImageURLTB.FileContent.Length > 0 Then
            'Save the file to Employees folder for later retrieval
            ImageURLTB.SaveAs("images\Employees" & ImageURLTB.FileName)
            DataConnection.UpdateParameters("ImageURL").DefaultValue = "images\Employees" + ImageURLTB.FileName
        End If

When I click the button, I receive an error, "NullReference Exception was unhandled by user code.  Object reference not set to an instance of the object."  Any suggestions?

    End Sub
Avatar of GavinMannion
GavinMannion

I am presuming from your code that the control is inside a GridView?

If so you will need to use the RowCommand event and not the UploadImage_Click event to get this control and the use it.

If it is not in a GridView Drop the dollowing line, it is not required.

Dim ImageURLTB As FileUpload = Gridview1.FindControl("ImageURLTB")
Avatar of goodmanro

ASKER

Gavin,
Yes it is in a GridView.  I changed the Sub to Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs).  This didn't seem to work either.  It is still throwing the NullReferenceException at this line:

  If ImageURLTB.FileContent.Length > 0 Then          <-----------------------------------------------NullReferenceException Error
            'Save the file to Employees folder for later retrieval
            ImageURLTB.SaveAs("images\Employees" & ImageURLTB.FileName)
            DataConnection.UpdateParameters("ImageURL").DefaultValue = "images\Employees" + ImageURLTB.FileName
   End If

Thank you.
That would be because the ImageURLTB is not being found correctly.

Inside the RowCommand event you need to cast the GridViewCommandEventArgs e to be your FileUpload...

eg

Dim ImageURLTB As FileUpload = e.CommandSource
ImageURLTB.SaveAs(ImageURLTB.FileName)


My VB is not so good but you should get the idea from here.
I receive the error: Unable to cast object of type 'System.Web.UI.WebControls.GridView' to type 'System.Web.UI.WebControls.FileUpload'.
ASKER CERTIFIED SOLUTION
Avatar of GavinMannion
GavinMannion

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I used this:

Dim ImageURLTB As FileUpload = CType(Gridview1.Rows(Convert.ToInt32(e.CommandArgument)).FindControl("ImageURLTB"), System.Web.UI.WebControls.FileUpload)

I stil get the NullReferenceException listed above.  I appreciate your continued help...
grrrr... I hate bugs that won't go away :)

When you debug and check the new Control (ImageURLTB) that you have casted does it look like one?

Also change your if statement to be

If ImageURLTB.FileName.Length > 0 Then          <-----------------------------------------------NullReferenceException Error
            'Save the file to Employees folder for later retrieval
            ImageURLTB.SaveAs("images\Employees" & ImageURLTB.FileName)
            DataConnection.UpdateParameters("ImageURL").DefaultValue = "images\Employees" + ImageURLTB.FileName
   End If

Gavin,
I have posted the entire Sub.  I changed a few things along the way, but none of it should be causing this error.  I also tried modifying the HasFile line as you suggested above.  This bug is pesky!  Thank you!  

--------------------------------------------------------------------------------------------------------------
Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)

        Dim ImageURLTB As FileUpload = CType(Gridview1.Rows(Convert.ToInt32(e.CommandArgument)).FindControl("ImageURLTB"), System.Web.UI.WebControls.FileUpload)
       
       Dim UploadStatusLabel As Label = Gridview1.FindControl("UploadStatusLabel")

        ' Specify the path on the server to
        ' save the uploaded file to.

        Dim savePath As String = "images\Employees"

        ' Before attempting to save the file, verify
        ' that the FileUpload control contains a file.
        If ImageURLTB.FileName.Length > 0 Then                  <-----------------------------------------------NullReferenceException Error


            ' Get the name of the file to upload.
            Dim fileName As String = ImageURLTB.FileName

            ' Get the extension of the uploaded file.
            Dim extension As String = System.IO.Path.GetExtension(fileName)

            ' Get the size in bytes of the file to upload.
            Dim fileSize As Integer = ImageURLTB.PostedFile.ContentLength

            ' Allow only files less than 5,100,000 bytes (approximately 5 MB) to be uploaded.

            ' Allow only files with .jpb or .gif extensions
            ' to be uploaded.
           
        If (extension = ".gif") Or (extension = ".jpg") And (fileSize < 5100000) Then
                Try

                    ' Append the name of the file to upload to the path.
                    savePath += fileName

                    ' Call the SaveAs method to save the
                    ' uploaded file to the specified path.
                    ImageURLTB.SaveAs(savePath)

                    'Updating SqlDataConnection parameter
                    DataConnection.UpdateParameters("ImageURL").DefaultValue = "images\Employees" + ImageURLTB.FileName

                    ' Notify the user that their file was successfully uploaded.
                    UploadStatusLabel.Text = "Your file was uploaded successfully."

                Catch ex As Exception
                    UploadStatusLabel.Text = "ERROR: " & ex.Message.ToString()

                End Try

            Else
                ' Notify the user why their file was not uploaded.
                UploadStatusLabel.Text = "Your file was not uploaded because " + _
                                         "it does not have a .jpg or .gif extension."
            End If

        Else
            ' Notify the user that a file was not uploaded.
            UploadStatusLabel.Text = "You did not specify a file to upload."
        End If


    End Sub
Okay change

Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)

to

Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)

also try putting a break point on the line that you cast the FileUpload object and then viewing it by righclicking and saying Quickwatch. It should give you a bunch of information. If it doesn't then something is wrong there.

I am leaving work now but will be back online in about 2 hours.. If someone else can see where it is going wrong please jump in....
I have updated the Sub to what you have suggested above (and also renamed the OnRowCommand="GridView1_RowCommand" in the GridView1).  I have tried putting a break point on that line, but I'm not seeing the options that you speak of.

Ideas?
This doesn't make any sense at the moment, it should not be this difficult :(

I am not exactly sure what is going on here.....

Okay so I am presuming you are using Visual Studio (let me know if that is incorrect)

Put a break point on the line
 Dim UploadStatusLabel As Label = Gridview1.FindControl("UploadStatusLabel")

When that breakpoint get hit during run time (Let me know if it doesn't get hit)

Right click on the [FileUpload] object 1 line above and say "QuickWatch"

A new window should popup and hopefully in the textbox at the top it says "FileUpload" and in the grid beneath it a whole bunch of lines.

If it does this then we are finding the control. If it has 1 line which says something along the lines of Invalid or Cannot evaluate expression then it cannot find the control.

If it cannot find it can you post the html portion of the code as well and let me know which button you are pushing to get this to postback.

If it does work then we are casting the control correctly and something else is going wrong.

I am sure this is something small that is going wrong and am still hoping someone else will jump in :)...
Let me know though
Hi Gavin,

Ill take a look although im not promising anything... im an ASP guy at the moment just trying to find the time to move over to asp.net!

Ill put this in visual studio and have a look.

Cheers,
Carl
Yes.  I am using VS2005.  When I add the QuickWatch to the control, this is the message that is displayed:

FileUpload      'FileUpload' is a type and cannot be used as an expression.

I also receive this for the FindControl in that same line:      

FindControl      Overload resolution failed because no accessible 'FindControl' accepts this number of arguments.      
In addition,
This is displayed in the QuickWatch on the CType:

CType(Gridview1.Rows(Convert.ToInt32(e.CommandArgument)).FindControl("ImageURLTB"), System.Web.UI.WebControls.FileUpload)

Value: Nothing      Type: System.Web.UI.WebControls.FileUpload
What happens in the quick watch if you take a look at [ImageURLTB]?

.....................
I think I have an idea :)
When you populate the GridView on page_load do you have your population code inside an

If Not IsPostBack Then
'Populate GridView
End If

If not then the grid is being repopulated and you are trying to access something that may not exist yet... Make sense?
I'm actually populating the datagrid in my aspx file (probably not the best coding technique).  I just have Bind statements in the aspx.  Should I take them out and load the values of each column in a If Not IsPostBack statement?  If not, is there a way that I can correct this with my current code?

Thanks -
You can use your current code, just move the .Bind() part into a IsPsotBack codeblock.....

Make sure that viewstate is turned on (this is true by default) and then you should be able to get to the data.
Either way, it looks like I am going to have to recode the Bind statments (get out of the spiderweb code mentaility).  Any suggestions with the following code?

My GridView is as follows:

<asp:Gridview ID="Gridview1" runat="server"
            DataSourceID="DataConnection"
            DataKeyNames="EmpID"
            AutoGenerateColumns="False"
            AllowSorting="True"
            Style="float:left"
            AllowPaging="True"
            AutoGenerateEditButton="True"
            OnRowDataBound="Gridview1_RowDataBound"
            OnRowCommand="GridView1_RowCommand"
            OnSorting="GridView1_Sorting"
            SkinID="Professional"
            Font-Name="Verdana"
            Font-Size="10pt"
            Cellpadding="4"
            HeaderStyle-BackColor="#444444"
            HeaderStyle-ForeColor="#ffffff"
            AlternatingRowStyle-BackColor="#dddddd">
             
        <Columns>
       
<asp:BoundField HeaderText="ID" DataField="EmpID" ReadOnly="True"/>
       
        <asp:TemplateField HeaderText="Name" SortExpression="FullName">
        <ItemTemplate>    
            <asp:Label ID="FullNameLabel" runat="server" Text='<%# Bind("FullName") %>' Width="200px"/>
        </ItemTemplate>
       
        <EditItemTemplate>
            <asp:TextBox ID="FullNameTB" runat="server" Text='<%# Bind("FullName") %>' Width="200px"/>
        </EditItemTemplate>
       
        <FooterTemplate>
            <asp:TextBox ID="Edit_FullName" runat="server" Visible="True" />
        </FooterTemplate>
        </asp:TemplateField>
               
        <asp:TemplateField HeaderText="Job Title" SortExpression="JobTitle">
       
            <ItemTemplate>
                <asp:Label ID="JobTitleLabel" runat="server" Text='<%# Bind("JobTitle") %>' />
            </ItemTemplate>
       
            <EditItemTemplate>
                <asp:DropDownList DataSourceID="DropDownJob" DataTextField="JobTitle" DataValueField="JobTitleID"
                 ID="DropDownBoxJobTitles" runat="server" SelectedValue='<%# Bind("JobID") %>' />
            </EditItemTemplate>
           
        <FooterTemplate>
            <asp:DropDownList DataSourceID="DropDownJob" DataTextField="JobTitle" DataValueField="JobTitleID"
                 ID="Edit_JobID" runat="server" />
        </FooterTemplate>
       
        </asp:TemplateField>
       
        <asp:TemplateField HeaderText="Inactive?" SortExpression="Inactive">
       
            <ItemTemplate>
                <asp:Label ID="InactiveLabel" runat="server" Text='<%# IIf(Eval("Inactive") = "True", "Yes", "No") %>' />
            </ItemTemplate>
       
            <EditItemTemplate>
                <asp:CheckBox ID="CheckEdit" Checked='<%# Bind("Inactive") %>' Visible="True" runat="server" />
            </EditItemTemplate>
           
        <FooterTemplate>
            <asp:CheckBox ID="Edit_Inactive" Visible="True" runat="server" />
        </FooterTemplate>
       
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Email Address" SortExpression="EmailAddress">
        <ItemTemplate>    
            <asp:Label ID="EmailAddressLabel" runat="server" Text='<%# Bind("EmailAddress") %>' Width="200px" />
        </ItemTemplate>
       
        <EditItemTemplate>
            <asp:TextBox ID="EmailAddressTB" runat="server" Text='<%# Bind("EmailAddress") %>' Width="200px"/>
        </EditItemTemplate>
       
        <FooterTemplate>
            <asp:TextBox ID="Edit_EmailAddress" runat="server" Visible="True" />
        </FooterTemplate>
        </asp:TemplateField>          
               
               
               
        <asp:TemplateField HeaderText="Image URL" SortExpression="ImageURL">
                <ItemTemplate>
                <a href="<%# Eval("ImageURL")%>" target="PictureFrame">View Photo</a>
                 </ItemTemplate>
         
                <EditItemTemplate>
                     <asp:FileUpload id="ImageURLTB" AlternateText="You cannot upload files" runat="server" />
       <hr />
       
       <asp:Label id="UploadStatusLabel"
           runat="server">
       </asp:Label>

                </EditItemTemplate>
        <FooterTemplate>
            <asp:TextBox ID="Edit_ImageURL" runat="server" />
            <asp:Button ID="Button1" Runat="server" Text="Add" OnClick="Button1_Click" />
            <asp:Button ID="CancelButton1" Runat="server" Text="Cancel" OnClick="CancelButton1_Click" />
        </FooterTemplate>
        </asp:TemplateField>
       
     <asp:TemplateField HeaderText="Select">
     <ItemTemplate>
   <asp:Button ID="btnDelete" Text="Delete" runat="server"
    OnClientClick="return confirm('Are you sureyou want to delete this record?');"
    CommandName="Delete" />

     </ItemTemplate>
   </asp:TemplateField>
           
        </Columns>
       
</asp:Gridview>

I see nothing wrong with the grid. How are you entering edit mode though?

Could you also paste your Page_Load event in the codebehind, I am struggling to understand why this normally simple operation is not working.
I have this in the OnRowCommand.  I have also tried a variation of this code in the OnRowUpdating.  In the code above, there is an OnRowCommand with this functions value.

    Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
        If Not IsPostBack Then

            Dim ImageURLTB As FileUpload = CType(Gridview1.Rows(Convert.ToInt32(e.CommandArgument)).FindControl("ImageURLTB"), System.Web.UI.WebControls.FileUpload)
            Dim UploadStatusLabel As Label = Gridview1.FindControl("UploadStatusLabel")


            ' Specify the path on the server to
            ' save the uploaded file to.

            Dim savePath As String = "images\Employees"

            ' Before attempting to save the file, verify
            ' that the FileUpload control contains a file.
            If ImageURLTB.HasFile Then

                ' Get the name of the file to upload.
                Dim fileName As String = ImageURLTB.FileName

                ' Get the extension of the uploaded file.
                Dim extension As String = System.IO.Path.GetExtension(fileName)

                ' Get the size in bytes of the file to upload.
                Dim fileSize As Integer = ImageURLTB.PostedFile.ContentLength

                ' Allow only files less than 5,100,000 bytes (approximately 5 MB) to be uploaded.

                ' Allow only files with .jpg or .gif extensions
                ' to be uploaded.

                If (fileSize < 5100000) Then
                    Try

                        ' Append the name of the file to upload to the path.
                        savePath += fileName

                        ' Call the SaveAs method to save the
                        ' uploaded file to the specified path.
                        ' This example does not perform all
                        ' the necessary error checking.              
                        ' If a file with the same name
                        ' already exists in the specified path,  
                        ' the uploaded file overwrites it.
                        ImageURLTB.SaveAs(savePath)

                        'Updating SqlDataConnection paramter
                        DataConnection.UpdateParameters("ImageURL").DefaultValue = "images\Employees\" + ImageURLTB.FileName

                        ' Notify the user that their file was successfully uploaded.
                        UploadStatusLabel.Text = "Your file was uploaded successfully."

                    Catch ex As Exception
                        UploadStatusLabel.Text = "ERROR: " & ex.Message.ToString()

                    End Try

                Else
                    ' Notify the user why their file was not uploaded.
                    UploadStatusLabel.Text = "Your file was not uploaded because " + _
                                             "it does not have a .jpg or .gif extension."
                End If

            Else
                ' Notify the user that a file was not uploaded.
                UploadStatusLabel.Text = "You did not specify a file to upload."
            End If

        End If



    End Sub
I also get this error after the row update:

Cannot insert the value NULL into column 'ImageURL', table 'BBNC_Backlog.dbo.LOOKUP_Employees'; column does not allow nulls. UPDATE fails.
The statement has been terminated.

It looks like it is still not getting a value for the ImageURL in the Gridview1_RowCommand.  If I add a default value, like default.gif to the ImageURL insert parameter, it works but it inserts that default value.
You must not put this line

If Not IsPostBack Then

inside your RowCommand event

I presume it is still falling over on your 'if' statement?

What is inside the Page_Load event? I still feel the grid is being rebound and that is why you cannot find anything.
I do not have a Page_Load sub.  In addition, if I leave out the If Not IsPostBack, I get a NullReferenceException on this line:

If ImageURLTB.HasFile Then
But that makes no sense,

If Not IsPostBack means that code will only run the first time that page is loaded. Which won't happen anyway because that is an event that needs to be called from the page which means the page has to be loaded to work.

and how can you not have a Page_Load event? Are you not using Visual Studio and codebehind?

This is making no sense at all.

Can you send me the actual file by email so I can understand what is going on? ([myusername] at gmail.com)

Not a problem, Gavin.  I appreciate all of your help.  I'm sending it now...
Gavin - GMail is blocking the .zip extension and .aspx.vb / .aspx extensions.  Do you have an FTP?
Gavin,
I solved this problem this afternoon:

    Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
        Dim ImageURLTB As FileUpload = Gridview1.Rows(e.RowIndex).FindControl("ImageURLTB")

It needs to happen during the row update event.  In addition, the FindControl object must be referenced as listed above.

I appreciate your help.  This question may be closed and removed.
Wow am I happy that this question is finished :)..

Sometimes the most simple thing will elude you forever. Well Done.

To close this question you need to post a request in Community Support [https://www.experts-exchange.com/Community_Support/]

Gavin,
I would like to reward you with the points as your posting led me to the answer.  Thank you again...