Получение NullReferenceException от .Select (), когда .Count () больше нуля LINQ to XML - PullRequest
3 голосов
/ 23 декабря 2011

У меня есть XML-файл:

<Org href="https://vcloudserver/api/v1.0/org/272521719" type="application/vnd.vmware.vcloud.org+xml" name="blah-blah" xmlns="http://www.vmware.com/vcloud/v1">
     <Link href="https://vcloudserver/api/v1.0/vdc/1093121285" type="application/vnd.vmware.vcloud.vdc+xml" name="blah-haha" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/vdc/1213262741" type="application/vnd.vmware.vcloud.vdc+xml" name="blah-hoho" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/tasksList/272521719" type="application/vnd.vmware.vcloud.tasksList+xml" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/catalog/1309520800" type="application/vnd.vmware.vcloud.catalog+xml" name="blah-hehe" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/org/272521719/catalog/1309520800/controlAccess/" type="application/vnd.vmware.vcloud.controlAccess+xml" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/org/272521719/catalog/1309520800/action/controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" rel="controlAccess"/>
     <Link href="https://vcloudserver/api/v1.0/network/1435818199" type="application/vnd.vmware.vcloud.network+xml" name="blah-whodat" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/network/2048048931" type="application/vnd.vmware.vcloud.network+xml" name="blah-disis" rel="down"/>
     <Description/>
     <FullName>Blah diddy Blah-Blah</FullName>
</Org>

Итак, учитывая следующее:

XNamespace nameSpace = "http://www.vmware.com/vcloud/v1";
var doc = XDocument.Parse(xml);

Когда я отлаживаю следующий код в непосредственном окне VS:

doc.Root.Elements(nameSpace + "Link").Count()

Я получаю ожидаемое значение, 8. Но когда я продвигаюсь немного дальше, используя вещи:

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new vDC()
  {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
  }).Where(x=>x.Type.Contains("vdc"));

Я получаю исключение NullReferenceException, пытаясь получить доступ к vdcs.Count ().Я слишком долго возился с этим ... У меня есть другие места, где подобные вещи работают нормально, так что это не помогает.:( Попытался заполнить ToList () перед Where () и просто переместить исключение NullReferenceException до этого вызова.

Если это помогает, vDC в настоящее время определяется как:

public class vDC
{
  public string Name { get; set; }
  public string Type { get; set; }
  public string Href { get; set; }
}

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Некоторые элементы Link не имеют атрибута name, поэтому:

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new vDC()
  {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
  }).Where(x=>x.Type.Contains("vdc"));

задыхается от

Name = x.Attribute("name").Value

, поскольку в некоторых случаях x.Attribute("name") равно null.

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new 
  {
    NameAttr = x.Attribute("name"),
    TypeAttr = x.Attribute("type"),
    HrefAttr = x.Attribute("href")
  }).Select(x => new vDC()
  {
    Name = x.NameAttr == null ? null : x.NameAttr.Value,
    Type = x.TypeAttr == null ? null : x.TypeAttr.Value,
    Href = x.HrefAttr == null ? null : x.HrefAttr.Value, 
  }).Where(x=>x.Type.Contains("vdc"));

или подобное должно исправить вещи.

1 голос
/ 23 декабря 2011

Некоторые из ваших ссылок не имеют name - вместо них rel. NPE происходит от этого.

Вы видите это только тогда, когда звоните Count, потому что реальная оценка не произойдет до тех пор.

Чтобы изменить код для защиты от NPE, добавьте условие Where:

var vdcs = doc.Root.Elements(nameSpace + "Link")
.Where(x => x.Attribute("name") != null && x.Attribute("type") != null && x.Attribute("value") != null)
.Select(x => new vDC {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
}).Where(x=>x.Type.Contains("vdc"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...