I am using the NetDataContractSerializer. I can create, add and serialize objects into data file no problem; reloading the file into the GUI has no issue.

However I run into a problem when I attempt to delete(remove) objects from the data and resave (serialize) the data.

Here is my delete room button; when a user requests the deletion of a room on a particular floor, the program will create a list of objects that reside within that particular room on that particular floor. Then delete them, close the current form they are viewing and save the data.

This seems to work, as the program does not crash and the room is removed from the list of rooms on the current floor.

However when I attempt to reload the file ( close program, open and load) I get this error:

"There was an error deserializing the object . The data at the root level is invalid. Line 1, position 1."

Here is my deleteRoom Button

      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();
        }
    }

Here is my CRUD for the method 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.");
        }
    }

Here is my 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();
    }
}
有帮助吗?

解决方案

I think your problem might beFileMode.OpenOrCreate. Make that just FileMode.Create or you'll have an unwanted tail from the original (longer) file.

And, side topic, do use using() {} blocks to work with FileStreams.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top