NullReferenceException при использовании XElement - PullRequest
0 голосов
/ 30 августа 2011

У меня есть метод, который предполагает редактировать XML-файл:

    public void EditItem(Item item, string xml)
    {
        Data = XDocument.Load(HttpContext.Current.Server.MapPath("~/App_Data/Items/" + xml + ".xml"));

        XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == item.ID).FirstOrDefault();

        node.SetElementValue("ID", item.ID);
        node.SetElementValue("Name", item.Name);
        node.SetElementValue("Type", item.Type);
        node.SetElementValue("Kr", item.Kr);
        node.SetElementValue("Euro", item.Euro);

        Data.Save(HttpContext.Current.Server.MapPath("~/App_Data/Tables/" + xml + ".xml"));
    }

Я получаю эту ошибку проверки при попытке / перехвате в моем контроллере: «Ссылка на объект не установлена ​​для экземпляра объекта«.Посредством некоторой отладки я обнаружил, что «узел» является нулевым, хотя «Данные» содержат все правильные данные из XML, а модель.ID верна.

странно то, что у меня это естьработа в другом репозитории, где xml не является динамическим, а объект XDocument загружен в конструктор.

Есть идеи, чем это вызвано?Или, может быть, некоторые идеи об обходном пути.

Обновление.Фрагмент XML:

<?xml version="1.0" encoding="utf-8"?>
    <catagory id="0">
      <module>
        <item>
          <ID>101</ID>
          <Name>ClassicoTable(35x100x100)</Name>
          <Type>Model</Type>
          <Kr>0</Kr>
          <Euro>0</Euro>
          <DataType>ClassicoTableA</DataType>
        </item>
        <item>
          <ID>100</ID>
          <Name>ClassicoTable(102x100x140)</Name>
          <Type>Model</Type>
          <Kr>0</Kr>
          <Euro>0</Euro>
          <DataType>ClassicoTableB</DataType>
        </item> 



       ......

      </module>
    </catagory id="0">

Ответы [ 2 ]

1 голос
/ 30 августа 2011

Если эта строка:

XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == table.ID).FirstOrDefault();

будь таким (не уверен, откуда table.ID взято):

XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == item.ID).FirstOrDefault();

Я бы также проверил, является ли узел нулевым:

public void EditItem(Item item, string xml)
{
    Data = XDocument.Load(HttpContext.Current.Server.MapPath("~/App_Data/Items/" + xml + ".xml"));

    XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == item.ID).FirstOrDefault();

    if (node != null)
    {
        node.SetElementValue("ID", item.ID);
        node.SetElementValue("Name", item.Name);
        node.SetElementValue("Type", item.Type);
        node.SetElementValue("Kr", item.Kr);
        node.SetElementValue("Euro", item.Euro);

        Data.Save(HttpContext.Current.Server.MapPath("~/App_Data/Tables/" + xml + ".xml"));
    }
}
0 голосов
/ 31 августа 2011

Хорошо, нашел решение.Я начал задаваться вопросом, почему @Kim хотел фрагмент из моего XML.Таким образом, это заставило меня думать, что Data.Root.Element(), возможно, не был правильным путем.Поэтому я попробовал вместо Descendants(), и это действительно работает.Зачем?Я понятия не имею.Вот почему:

В другом репо у меня есть XDocument.load() в конструкторе репо.Я подумал, что это будет хорошо, потому что тогда мне не придется повторять один и тот же код во всех методах CRUD.Но так как я хотел xml-динамику, а конструктор не принимает параметры, я подумал, что этот путь (оригинальный вопрос) будет в порядке.Вот код из «статического» репо:

//Constructor
public CubeRepository()
{
    allCubes = new List<Cube>();

    CubeData = XDocument.Load(HttpContext.Current.Server.MapPath("~/App_Data/Cubes/Cubep10p11.xml"));
    var cubes = from cube in CubeData.Descendants("item")
                select new Cube(cube.Element("ID").Value, 
                    cube.Element("Name").Value, 
                    cube.Element("Type").Value,
                    (int)cube.Element("Kr"),
                    (int)cube.Element("Euro"));

    allCubes.AddRange(cubes.ToList<Cube>());
}

И в моем методе редактирования этого репо:

public void EditCube(Cube cube)
{
    XElement node = CubeData.Root.Elements("item").Where(i => (string)i.Element("ID") == cube.ID).FirstOrDefault();
    node.SetElementValue("ID", cube.ID);
    node.SetElementValue("Name", cube.Name);
    node.SetElementValue("Type", cube.Name);
    node.SetElementValue("Kr", cube.Kr);
    node.SetElementValue("Euro", cube.Euro);

    CubeData.Save(HttpContext.Current.Server.MapPath("~/App_Data/Cubes/Cubep10p11.xml"));
}

И это работает, как я очаровываю, хотя я использую CubeData.Root.Elements("item").Примечание: Elements от Descendants.Структура XML-файлов идентична.

...