1
votes

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?

1
Look at what is null, thisKeyword, x, or x.Value will kill you. Have to do a null check first. - Tony Hopkinson
I think that you can use the following code thisKeyword?.ToUpper().Contains((string)x?.Value.ToUpper() ?? "~") for checking that both aren't null - ganchito55

1 Answers

1
votes

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)