0

我在获取 SOAP 服务以反序列化对象数组时遇到问题;它仅在数组的第一个成员中读取,仅此而已。这是我的代码:

public void StoreCredentials(Credentials credentials)
    {
        Credentials[] credsArray;
        var soap = new SoapFormatter();

        var stream = new FileStream(_path, FileMode.OpenOrCreate);
        try
        {
            credsArray = (Credentials[])soap.Deserialize(stream);
            var credsList = credsArray.ToList();
            credsList.Add(credentials);
            credsArray = credsList.ToArray();
        }
        catch (SerializationException)
        {
            credsArray = new[] {credentials};
        }
        soap.Serialize(stream, credsArray);
        stream.Close();
    }

我编写了一个简单的单元测试,它将两个 Credentials 对象添加到文件中,输出看起来正确,两组凭据都存在,但是当我运行测试以将第三组添加到文件时,soap.Deserialize(stream) 行返回一个只有一个条目的数组,即使它读取的文件包含两个条目。我在这里做错了吗?有没有更好/更简单的方法来做到这一点?请帮忙!

4

1 回答 1

0

我想到了。问题出在 FileStream 的 FileMode.OpenOrCreate 属性上。这将打开文件,但将其附加一个新集合,而不是更改原始集合。我需要改用 FileMode.Create 覆盖文件,所以这是工作代码(我还将集合更改为 Hashtable,效果更好):

public void StoreCredentials(Credentials credentials)
    {
        credentials.Encrypt(_myUser.Encryption);
        Hashtable credsTable;
        var soap = new SoapFormatter();

        FileStream stream;
        try
        {
            stream = new FileStream(_path, FileMode.Open, FileAccess.ReadWrite);
            credsTable = (Hashtable) soap.Deserialize(stream);
            stream.Close();
            stream = new FileStream(_path, FileMode.Create, FileAccess.ReadWrite);
            if (credsTable.ContainsKey(credentials.Id))
                credsTable[credentials.Id] = credentials;
            else
                credsTable.Add(credentials.Id, credentials);
        }
        catch (FileNotFoundException e)
        {
            stream = new FileStream(_path, FileMode.Create, FileAccess.ReadWrite);
            credsTable = new Hashtable {{credentials.Id, credentials}};
        }
        soap.Serialize(stream, credsTable);
        stream.Close();
    }
于 2013-01-31T23:20:30.480 回答