Ошибка сериализации после удаления объекта (NetDataContractSerializer) - PullRequest
1 голос
/ 22 марта 2012

Я использую NetDataContractSerializer. Я могу создавать, добавлять и сериализовать объекты в файл данных без проблем; перезагрузка файла в графический интерфейс не имеет проблем.

Однако я сталкиваюсь с проблемой, когда пытаюсь удалить (удалить) объекты из данных и восстановить (сериализовать) данные.

Вот моя кнопка удаления комнаты; когда пользователь запрашивает удаление комнаты на определенном этаже, программа создает список объектов, которые находятся в этой конкретной комнате на этом конкретном этаже. Затем удалите их, закройте текущую форму, которую они просматривают, и сохраните данные.

Кажется, это работает, поскольку программа не дает сбоя, и комната удаляется из списка комнат на текущем этаже.

Однако, когда я пытаюсь перезагрузить файл (закрыть программу, открыть и загрузить), я получаю эту ошибку:

"Произошла ошибка десериализации объекта. Данные на корневом уровне недействительны. Строка 1, позиция 1."

Вот моя кнопка deleteRoom

      private void btn_deleteRoom_Click(object sender, EventArgs e)
    {
        var assets = getAssetsForCurrentRoom();
        string warningMessage = "Deleting this room will delete this room and all contained assets! Are you sure you want to do this?";
        string caption = "WARNING!";
        MessageBoxButtons buttons = MessageBoxButtons.YesNo;
        DialogResult result;
        //Display the MessageBox
        result = MessageBox.Show(warningMessage, caption, buttons);
        if (result == System.Windows.Forms.DialogResult.Yes)
        {
            var itemsToRemove = new ArrayList();
            foreach (var item in currentHouse.GetAssets())
            {
                if (item.Parent.Name == currentRoom.Name)
                {
                    itemsToRemove.Add(item);
                }
            }
            foreach (var item in itemsToRemove)
            {
                currentHouse.deleteAsset((Asset)item);
            }
            currentHouse.DeleteRoom(currentRoom);
            PersistanceController.SaveHouseWithCurrentPath(currentHouse);
            this.Close();
        }
    }

Вот мой CRUD для метода deleteAsset ()

public void deleteAsset(Asset asset)
    {
        //is null?
        if (asset == null)
        {
            throw new ArgumentNullException("asset", "Asset cannot be null.");
        }
        //is blank
        if (string.IsNullOrWhiteSpace(asset.Name))
        {
            throw new ArgumentNullException("asset", "Asset name cannot be blank | null.");
        }
        var listAsset = _assets.FirstOrDefault(existingAsset => (existingAsset.Name == asset.Name));
        if (listAsset != null)
        {
            _assets.Remove(asset);
        }
        else
        {
            throw new InvalidOperationException("Asset does not exist; thus it can not be deleted.");
        }
    }

Вот мой PersistanceController

 public static class PersistanceController
{

    public static string LastLoadedPath { get; set; }

    public static House LoadHouse(string path)
    {
        NetDataContractSerializer houseDeserializer = new NetDataContractSerializer();

        FileStream houseFileStream = new FileStream(path, FileMode.Open);
        House deserialzedHouse = (House)houseDeserializer.Deserialize(houseFileStream);

        houseFileStream.Close();

        LastLoadedPath = path;

        return deserialzedHouse;
    }

    public static void SaveHouseWithCurrentPath(House house)
    {
        SaveHouse(house, LastLoadedPath);
    }

    public static void SaveHouse(House house, string path)
    {

        //save house
        NetDataContractSerializer xmlSerializer = new NetDataContractSerializer();
        Stream streamWriter = new FileStream(path, FileMode.OpenOrCreate);
        xmlSerializer.Serialize(streamWriter, house);

        streamWriter.Close();
    }
}

1 Ответ

2 голосов
/ 22 марта 2012

Я думаю, что ваша проблема может быть FileMode.OpenOrCreate.Сделайте это просто FileMode.Create или вы получите нежелательный хвост из оригинального (более длинного) файла.

И, побочный вопрос, используйте блоки using() {} для работы с FileStreams.

...