1

I am receiving the following error when trying to access an XML element that doesnt exist using linq:

A first chance exception of type 'System.NullReferenceException' occurred in Test.exe System.NullReferenceException: Object reference not set to an instance of an object.

bool exists = website.Parent
            .Element("Exclusions")
            .Elements("Exclusion")
            .Where(x => thisKeyword.ToUpper().Contains((string)x.Value.ToUpper() ?? "~"))
            .Any();

I can remedy the issue by simply using .Where(x => thisKeyword.Contains((string)x))

But I need to convert both thisKeyword and the XML element value (if it exists) to upper case to get a case-insensitive comparison.

I was under the impression that ?? "~" meant that "if whats the left is null use what is to the right. So in this case x should become tilde, and therefore not validate against thisKeyword (as it wont ever contain tilde). A crude method I agree...but it doesn't even work.

How can I protect against the NullReferenceException?

3
  • 2
    Possible duplicate of What is a NullReferenceException, and how do I fix it? Commented Mar 12, 2017 at 23:09
  • Look at what is null, thisKeyword, x, or x.Value will kill you. Have to do a null check first. Commented Mar 12, 2017 at 23:11
  • 1
    I think that you can use the following code thisKeyword?.ToUpper().Contains((string)x?.Value.ToUpper() ?? "~") for checking that both aren't null Commented Mar 12, 2017 at 23:12

1 Answer 1

1

Assuming that x.Value is null and thisKeyword is known to be non-null:

The crash is happening because the ?? operator is trying to check whether the value returned by ToUpper() is null. However, it can't call ToUpper() because x.Value does not exist.

In C# version 6 or later you can use the null propagation operator, ?., which accesses a property if and only if the object is non-null:

.Where(x => thisKeyword.ToUpper().Contains(
            (string)x.Value?.ToUpper() ?? "~")

Alternatively, just use a separate Where clause to check that x.Value is non-null:

.Where(x => x.Value != null)
.Where(x => thisKeyword.ToUpper().Contains(x.Value.ToUpper())

As an aside, you could put the condition inside the Any() clause instead:

.Elements("Exclusion")
.Any(x => x.Value != null && thisKeyword.ToUpper().Contains(x.Value.ToUpper())

And you don't necessarily need to convert to upper case either:

.Any(x => x.Value != null &&
          thisKeyword.IndexOf(x.Value,
             StringComparison.InvariantCultureIgnoreCase) > 0)
Sign up to request clarification or add additional context in comments.

2 Comments

You are on the right track, but instead of messing around with the Elvis operator you can instead use something far simpler - the string.Equals(string, string, comparisonType) static method.It is tolerant of nulls, and you can specify a case insensitive check (which is the most common reason why people do a ToUpper() or ToLower() before checking).
Thanks for this. It looks like I cannot use the Value?. property so I must be on an older version of C#. My next issue is how I should deal with NullReferenceException if .Elements("Exclusion") and .Element("Exclusions") do not exist in the XML?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.