Solved

What to do about NullReferenceException?

Posted on 2009-05-14
5
304 Views
Last Modified: 2012-05-07
Hey everyone,

I'm reading an XML document, and assigning the attribute values to various textboxes.  This works perfectly fine so long as the attributes are there, if they aren't I get a NullReference exception.  

As my code is like the following:
 txtPostalName.Text = nodeCorAdd.Attributes.GetNamedItem("postalname").Value;

What can I do if the attribute isn't in the XML document?  I really don't want to have go:
if(nodeCorAdd.Attributes.GetNamedItem("postalname").Value != null) for each attribute.  
0
Comment
Question by:angus_young_acdc
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
5 Comments
 
LVL 11

Expert Comment

by:William
ID: 24385118
if you perform a loop for all your items and test for null - you can set them to string.empty if they are null, then when populating your textboxes it will not bomb on yu
0
 
LVL 12

Expert Comment

by:GuitarRich
ID: 24385204
you could write a routine to convert to NonNullableString like this:
private string ToNonNullableString(object value)
{
    string result = string.empty;
    if (value != null)
    {
        result = value.ToString();
    }
    return result;
}
 
// Then call it like this:
txtPostalName.Text = ToNonNullableString(nodeCorAdd.Attributes.GetNamedItem("postalname").Value);

Open in new window

0
 
LVL 16

Expert Comment

by:ToddBeaulieu
ID: 24385239
Actually, I think your example check is checking the value of the item for null, but if the attribute doesn't exist, won't THAT check fail because the object reference is NULL, thereby preventing checking its value. I assume that's how GetNamedItem works ... by returning a null if it's not found.

Anyway, why not create a small wrapper function that does both checks. Then you just call the wrapper, once for each field.

Off the top of my head, I don't know the Class names returned by these, so I'll use "var" as a placeholder...

MyWrapperToSetFieldValue(txtPostalName, "postalname");

private void MyWrapperToSetFieldValue(Control ctl, string fieldName)
{
    var node = nodeCorAdd.Attributes.GetNamedItem(fieldName);
    if (var != null && var.Value != null)
    {
        ctl.Text = var.Value;
    }
    else {
       ctl.Text = string.empty; // can also use TextBox as the type, if they're all text boxes. and make wrapper classes for each type (overloading) or determnine type of control in here.
    }
}
0
 
LVL 9

Expert Comment

by:tculler
ID: 24385369
Well, which part is returning null--GetNamedItem, or the Value property of the returned item? Also, to clean up your code, you can use the "Coalesce" operator, written as "??". It works like this:

System.String someString = stringValuePossiblyNull ?? "Fallback if the value to the left is null";

The compiler, in this case, will check the value of "stringValuePossiblyNull"; if it is null, it will assign the vaule to the right of the coalesce operator. If it is not null, it will assign the value as usual.

Another option is to use an XML schema in which you require certain attributes. There are quite a few ways of going about your problem, but really, I hate to say it, but you're being lazy here. There's no reason you can't check for something as necessary as this--not everything can be just seamlessly built in and magically done FOR you.

Anyways, a more specific solution is provided in the following code snippet. If my thoughts are correct, it will still throw a NullReferenceException because I think you're checking the wrong value for "null", but we'll see :)

Hope it helps,
Nate
txtPostalName.Text = nodeCorAdd.Attributes.GetNamedItem("postalname").Value ?? System.String.Empty;
 
// If this doesn't work, and you're worried about too many lines, of code, you could use the following,
// assuming the returned item is null (which I'm thinking it is)
 
txtPostalName.Text = (nodeCorAdd.Attributes.GetNamedItem("postalname") != null) ?nodeCorAdd.Attributes.GetNamedItem("postalname").Value ?? System.String.Empty : System.String.Empty;
 
// This performs a check for both fields that may be null.

Open in new window

0
 
LVL 15

Accepted Solution

by:
angus_young_acdc earned 0 total points
ID: 24394089
Hey everyone, I solved my problem yesterday (but didn't have the chance to close the thread).  It isn't the most pretty solution, but it works.  What I ended up doing (similar to what was suggested after I done it) was to add a tag to each control, this tag was the attribute name.  Then when I attempt to get the data it will only pull back the attributes which exist, to do this I use the following:

 XmlNodeList listSecAdd = document.SelectNodes(_node);
                XmlNode nodeSecAdd;
                for (int i = 0; i < listSecAdd.Count; i++)
                {
                    nodeSecAdd = listSecAdd[i];
                    foreach (XmlAttribute att in nodeSecAdd.Attributes)
                    {
                        string theAttribute = att.Name.ToString();
                        foreach (Control secControl in tabAddress.Controls)
                        {
                            if (secControl.Name.Contains("txt")
                                && string.IsNullOrEmpty(secControl.Text))
                            {
                                if (secControl.Tag.ToString() == theAttribute)
                                {
                                    secControl.Text = nodeSecAdd.Attributes.GetNamedItem(theAttribute).Value;
                                    secControl.Enabled = true;
                                }
                                else
                                {
                                    secControl.Enabled = false;
                                }
                            }
                        }
                    }
                }

The reasoning behind disabling the control is so that the user won't enter data thinking it will be saved, so that only enabled text boxes (which are attributes in the XML) can be updated.  This means I can use the following to update:
 XmlNodeList securityList = document.SelectNodes(_node);
                XmlNode security;
                for (int i = 0; i < securityList.Count; i++)
                {
                    security = securityList[i];
                    foreach (Control secCont in tabAddress.Controls)
                    {
                        if (secCont.Enabled)
                        {
                            security.Attributes.GetNamedItem(secCont.Tag.ToString()).Value = secCont.Text;
                        }
                    }
                }
                document.Save(_xmlLocation);

tculler I wouldn't exactly call it lazy, more an attempt at code reduction and future proofing.  Currently there are over 110 different attributes which can be in the XML, these can be in any combination.  So, assuming that for the considerable future this throw away style app will have 110 controls, is it beneficial doing the == null check?  It seems like it may be an unnecessary amount of code to check if an attribute exists before populating or saving.  

I'm not overly sure if the method I have created is actually efficient, or potential pitfalls that may happen, so any advice would be great.
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question