What can cause FindControl() to throw a NullReferenceException?

7.4k Views Asked by At

I have a user control I'm building (ASP.NET 3.5, using C#).

This control is largely based on another, similar control (cut & paste inheritance, unfortunately, but there's no easy way to abstract this). The lines that are giving me trouble are directly copied from the other control, as is the majority of the display.

The relevant lines of code are as follows:

Panel pnlForm = (Panel)e.Item.FindControl("pnlForm");
Literal ltrAvailableCount = (Literal)e.Item.FindControl("ltrAvailableCount");

DropDownList drpLanguage = (DropDownList)pnlForm.FindControl("drpLanguage");
DropDownList drpShipTo = (DropDownList)pnlForm.FindControl("drpShipTo");
HiddenField hdnAvailableProductId = (HiddenField)pnlForm.FindControl("hdnAvailableProductId");

DropDownList drpQuantity = (DropDownList)pnlForm.FindControl("drpQuantity");
HiddenField hdnSelectedStyle = (HiddenField)e.Item.FindControl("hdnSelectedStyle");
Label lblStyleName = (Label)e.Item.FindControl("lblSelectedStyle");

pnlForm in the above is found correctly, as is ltrAvailableCount.

If I skip down to drpQuantity, it and the following lines work fine. However, when I run the lines for drpLanguage, drpShipTo, or hdnAvailableProductId FindControl throws a NullReferenceException.

I do not mean it returns 'null' and I try to access a property of the returned object, the method FindControl throws the exception. According to the MSDN library, this isn't possible - FindControl doesn't list anything as a potential thrown error, it just says that if it can't find the Control, it returns null.

What can cause FindControl to NullReferenceException?

-----------------Edit---------------

I should also mention that if I run any of the three problematic lines in the immediate window, I get the correct results. I can also see the controls in the ControlCollection of pnlForm when I inspect it while debugging.

-----------------2nd Edit-------------------

Just to confirm, I added another line: DropDownList notThere = (DropDownList)pnlForm.FindControl("notHere"); The control notHere is not anywhere on the page. The above line compiles (of course) and when I run the debugger, it runs fine. The cast goes fine. The variable notThere simply is null.

The underlying cause of this issue is NOT FindControl failing to find the controls and trying to cast null to a DropDownList or other Control

3

There are 3 best solutions below

7
On BEST ANSWER

It is NOT FindControl that's causing the problem.

The way you've got it coded it's performing two operations on one line - FindControl() and then the cast to the control datatype. It's the cast that's bombing, because the results of the FindControl call is a null value, and you're attempting to cast null to a control.

This one bit me many times, so I learned to code it as

object oDropDown1 = pnlForm.FindControl("DropDown1");

// then check if oDrowpDown 1 is null and cast if it's safe.

if(oDropDown1 != null)
{
   // here it's safe to cast.
}
2
On

You get a NullReferenceException, of it does not find a (the) control (you were looking for)

try:

DropDownList drpLanguage = (DropDownList)(pnlForm.FindControl("drpLanguage"));
DropDownList drpShipTo = (DropDownList)(pnlForm.FindControl("drpShipTo"));
HiddenField hdnAvailableProductId = (HiddenField)(pnlForm.FindControl("hdnAvailableProductId"));
4
On

casting null to a DropDownList will result in an exception.

if pnlForm.FindControl("drpQuantity") returns null you cannot cast it ;)

however this will work:

System.Web.UI.WebControls.DropDownList drpQuantity = 
   pnlForm.FindControl("drpQuantity") as System.Web.UI.WebControlsDropDownList;

if(drpQuantity!=null){
   //use drpQuantity here
}

The as operator is used to perform conversions between compatible type, The as operator is like a cast except that it yields null on conversion failure instead of raising an exception.

anyway, the use of findcontrol is only intended for data-generated controls, in all other cases use an interface (-implementation) to communicate with controls on usercontrols.

IMHO findcontrol is a feature that is abused globally.... ( kittens are killed for using it )