NullReferenceException была необработанной ошибкой при попытке получить атрибуты конфигурации

    public string GetLogName(string config)
    {
        XDocument xDoc = XDocument.Load(config);
        XElement[] elements = xDoc.Descendants("listeners").Descendants("add").ToArray();

        foreach (var element in elements)
        {
            if (element.Attribute("fileName").Value != null)
            {
                string filename = element.Attribute("fileName").Value;
                int location = filename.IndexOf("%");
                Console.WriteLine("string to return: " + filename.Substring(0, location));
                return filename.Substring(0, location);
            }
        }
    }

Я пытаюсь получить атрибут «fileName» из каждого элемента в массиве elements, но в некоторых случаях атрибут «fileName» не существует и выдает следующую ошибку: NullReferenceException не было обработано. В экземпляре объекта не задана ссылка на объект.

В моем случае есть два узла добавления, у которых нет атрибута fileName, но у третьего узла добавления он есть.

Как я могу пропустить записи, у которых нет атрибута fileName, или вы можете порекомендовать лучший способ получить этот атрибут?


person Pam    schedule 17.10.2013    source источник
comment
Практически все случаи NullReferenceException одинаковы. Пожалуйста, см. Что такое NullReferenceException в .NET? для некоторых советов.   -  person John Saunders    schedule 17.10.2013


Ответы (3)


Один из способов - отфильтровать список перед его обработкой:

XElement[] elements = xDoc.Descendants("listeners")
                          .Descendants("add")
                          .Where (d => d.Attribute("filename") != null )
                          .ToArray();

--- IMHO, вот как я бы переписал метод, используя linq и regex ---

var elements =
XDocument.Load(config);
         .Descendants("listeners")
         .Descendants("add")
         .Where (node => node.Attribute("filename") != null )
         .ToList();


return elements.Any() ? elements.Select (node => node.Attribute("filename").Value )
                                .Select (attrValue => Regex.Match(attrValue, "([^%]+)").Groups[1].Value)
                                .First ()
                      : string.Empty;
person ΩmegaMan    schedule 17.10.2013
comment
@Pam Спасибо ... см. Предложения по перезаписи. Обратите внимание на расширение .Select, которое является расширением проекта для изменения данных из одной формы в другую ... довольно мощно. GL - person ΩmegaMan; 17.10.2013
comment
Я решил использовать этот подход, чтобы отфильтровать другие узлы, вместо того, чтобы выполнять проверку позже. Я не знал, как написать предложение where для этого запроса, так что это действительно помогло. Спасибо! - person Pam; 17.10.2013

Вы можете сделать это, просто изменив эту строку:

if (element.Attribute("fileName").Value != null)

To:

if (element.Attribute("fileName") != null)
person cdhowie    schedule 17.10.2013

измените оператор if на это:

if (element.Attribute("fileName") != null)
person Jonesopolis    schedule 17.10.2013