开发者

Is this a serialisation error or a data contract error

I have this little method in a class library that is held in an external dll, away from the "client" app.

    public void SaveToDisk()
    {
        // Create a storage container and save
        // this instance to it. Use "this" storage name.
        var settingsToStore = this;
        var settings = IsolatedStorageSettings.ApplicationSettings;
        settings[StorageName] = settingsToStore;
        settings.Save();
    }

Essentially it stores itself to the phones isolated storage. The class that contains this is not marked with any attributes. The error I get is this:

ex {"Type 'CabbageWrapper.Account' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute."} System.Exception {System.Runtime.Serialization.InvalidDataContractException}

I would like to know what the error means rather than just adding attributes and praying that this works. Thanks!

EDIT: As requested, class in full.

using System.IO.IsolatedStorage;

public class Account
{

    public string Provider { get; private set; }

    public string ServerSymbol { get; private set; }

    public int MessageCharAllowance { get; private set; }

    public int RemainingWebtextAllowance { get; set; }

    public int WebtextAllowance { get; private set; }

    public string Username { get; private set; }

    public string Password { get; private set; }

    public string StorageName { get; private set; }

    public Account(string provider, string storageName, string username, string password)
    {
        // Assign the values to "this" instance.
        Provider = provider;
        Username = username;
        Password = password;
        StorageName = storageName;

        // Load the ServerSymbol and WebtextAllowance from
        // the libraries resources. These are known values.
        PopulateKnownData();

        // Save to disk
        SaveToDisk();
    }


    public Account(string storageName)
    {
        // We need to know the name of the storage 
        // container to perform the load. Get it
        // from the caller and save it to "this" instance.
        StorageName = storageName;

        // Perform the load.
        LoadFromDisk();
    }


    private void PopulateKnownData()
    {
        switch (Provider)
        {
            case "Vodafone":
                ServerSymbol = "v";
                WebtextAllowance = 600;
                RemainingWebtextAllowance = -1;
                break;

            case "O2":
                ServerSymbol = "o";
                WebtextAllowance = 250;
                RemainingWebtextAllowance = -1;
                break;

            case "Meteor":
                ServerSymbol = "m";
                WebtextAllowance = 250;
                RemainingWebtextAllowance = -1;
                break;

            case "Three":
                ServerSymbol = "t";
                WebtextAllowance = 333;
                RemainingWebtextAllowance = -1;
                break;

            default:
                break;
        }
    }


    public void LoadFromDisk()
    {
        // Create a dummy account for rehydration and
        // use it to grab the stored account from memory.
        Account storedAccount;
        IsolatedStorageSettings.ApplicationSettings.TryGetValue(StorageName, out storedAccount);

        // Use the stored details to hydrate this instance.
        Provider = storedAccount.Provider;
        ServerSymbol = storedAccount.ServerSymbol;
        RemainingWebtextAllowance = storedAccount.RemainingWebtextAllowance开发者_StackOverflow;
        WebtextAllowance = storedAccount.WebtextAllowance;
        MessageCharAllowance = storedAccount.MessageCharAllowance;
        Username = storedAccount.Username;
        Password = storedAccount.Password;
    }


    public void SaveToDisk()
    {
        // Create a storage container and save
        // this instance to it. Use "this" storage name.
        var settingsToStore = this;
        var settings = IsolatedStorageSettings.ApplicationSettings;
        settings[StorageName] = settingsToStore;
        settings.Save();
    }
}


The exception message is pretty self-explanatory. By decorating members with these attributes, you tell serializer what items are serialized (most of the time you want serialize only some members, not everything in your class). The reason why you must define them is simply that you can decide what to serialize and what not. There are also performance, security etc considerations, so this is reason why it's not done by default. Read http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx "Apply the DataContractAttribute attribute to classes, and the DataMemberAttribute attribute to class members to specify properties and fields that are serialized. "

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜