0

几天来,我一直在尝试解决这个愚蠢的问题,并且正在努力解决这个问题。如果有人有一个可行的示例,我会很高兴,因为到目前为止我发现的那些都不起作用:(我可以序列化基本类型,但不是对象。我对 DataContractAttribute 等感到非常困惑。我得到的错误是:

{“不应使用数据协定名称‘LocalStorage.Cat:http://schemas.datacontract.org/2004/07/SerializeListWinRT.DataModel’键入‘SerializeListWinRT.DataModel.LocalStorage+Cat’。考虑使用 DataContractResolver 或添加任何在已知类型列表中静态未知的类型 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。"}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using System.IO;
using System.Runtime.Serialization;
using Windows.Storage.Streams;


namespace SerializeListWinRT.DataModel
{
    class LocalStorage
    {
        [DataContractAttribute]
        public class Cat
        {
            [DataMember()]
            public String Name { get; set; }
        }

        static private Dictionary<string, object> _data = new Dictionary<string, object>();
        private const string filename = "items.xml";

        static public Dictionary<string, object> Data
        {
            get { return _data; }

        }

        static public T GetItem<T>(string key)
        {
            T result = default(T);

            if (_data.ContainsKey(key))
            {
                result = (T)_data[key];
            }

            return result;
        }

        static public bool ContainsItem(string key)
        {
            return _data.ContainsKey(key);
        }

        static async public Task Save()
        {
            await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
            {
                LocalStorage.SaveAsync().Wait();
            }, Windows.System.Threading.WorkItemPriority.Normal);
        }

        static async public Task Restore()
        {
            await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
            {
                LocalStorage.RestoreAsync().Wait();
            }, Windows.System.Threading.WorkItemPriority.Normal);
        }

        static async private Task SaveAsync()
        {
            _data.Add("cat", new Cat { Name = "Myname is" });
            _data.Add("dog", new Cat { Name = "Myname is" });

            StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
            IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
            IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
            DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>));
            sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);
            await sessionOutputStream.FlushAsync();
        }

        static async private Task RestoreAsync()
        {
            StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
            if (sessionFile == null)
            {
                return;
            }
            IInputStream sessionInputStream = await sessionFile.OpenReadAsync();
            DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>));
            _data = (Dictionary<string, object>)sessionSerializer.ReadObject(sessionInputStream.AsStreamForRead());
        }
    }
}

我是如何解决问题的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using System.IO;
using System.Runtime.Serialization;
using Windows.Storage.Streams;


namespace SerializeListWinRT.DataModel
{
    class LocalStorage
    {   
        [KnownType(typeof(SerializeListWinRT.Cat))]
        [DataContractAttribute]
        public class Cat
        {
            [DataMember()]
            public String Name { get; set; }
        }


    static private Dictionary<string, object> _data = new Dictionary<string, object>();
    private const string filename = "ngt.xml";

    static public Dictionary<string, object> Data
    {
        get { return _data; }

    }

    static public T GetItem<T>(string key)
    {
        T result = default(T);

        if (_data.ContainsKey(key))
        {
            result = (T)_data[key];
        }

        return result;
    }

    static public bool ContainsItem(string key)
    {
        return _data.ContainsKey(key);
    }

    static async public Task Save<T>()
    {
        await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
        {
            LocalStorage.SaveAsync<T>().Wait();
        }, Windows.System.Threading.WorkItemPriority.Normal);
    }

    static async public Task Restore<T>()
    {
        await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
        {
            LocalStorage.RestoreAsync<T>().Wait();
        }, Windows.System.Threading.WorkItemPriority.Normal);
    }

    static async private Task SaveAsync<T>()
    {
        _data.Add("cat", new Cat { Name = "Myname is" });
        _data.Add("dog", new Cat { Name = "Myname is" });

        StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
        IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
        IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
        DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>), new Type[] { typeof(T) });
        sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);
        await sessionOutputStream.FlushAsync();
    }

    static async private Task RestoreAsync<T>()
    {
        StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
        if (sessionFile == null)
        {
            return;
        }
        IInputStream sessionInputStream = await sessionFile.OpenReadAsync();
        DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>), new Type[] { typeof(T) });
        _data = (Dictionary<string, object>)sessionSerializer.ReadObject(sessionInputStream.AsStreamForRead());
    }
}

}

4

1 回答 1

3

我通过添加 KnownType 属性解决了这个问题

    [KnownType(typeof(SerializeListWinRT.Cat))]

但我以前没有这样做过,所以我不确定这是否是与 WinRT 相关的问题。哦,好吧,它现在可以工作了,但我仍然很好奇为什么你必须用 KnownType 属性来装饰..

于 2012-06-20T11:59:58.590 回答