字典类中的object对象可能是项目中的一个实体类,实体类已加上数据契约属性。
使用IFormatter接口,会提示要转换的实体类未加上序列化标识,估计是没有加上Serializable特性,但具体实体类不想再
加上该标识。
使用DataContractSerializer会提示找不到已知类型,请考虑使用 DataContractResolver,或将任何未知类型以静态方式添加到已知类型的列表。例如,可以使用 KnownTypeAttribute 特性,或者将未知类型添加到传递给 DataContractSerializer 的已知类型列表。请问怎样解决?

解决方案 »

  1.   

    Dictionary<string, string> dic1= new Dictionary<string, string>();
    dic1.Add("1", "1");
    dic1.Add("2", "2");
    MemoryStream ms = new MemoryStream();
    bf.Serialize(ms, dic1);  
    byte[] buffer = ms.GetBuffer();MemoryStream ms1 = new MemoryStream(buffer);
    Dictionary<string, string> dic2= (Dictionary<string, string>)bf.Deserialize(ms1);
      

  2.   

    2楼的方法我之前试过了,如果字典类中的value是一个string或int是没有任何问题的
    但如果是一个实体类型,但这个类型是一个项目中自定义的类,例如Person或Employee可能就会出问题
      

  3.   

    回4楼,我想实现一个这样的效果 
    我在数据库中建了一个二进制的字段,用来存放一些信息,在程序中将一个Dictionary<string,object>序列化成一个byte存到数据库中,取的时候在反序列化成一个字典类,而字典类中的value是一个object对象,有可能是我项目中的任何一个自定义实体类。
      

  4.   

    object 必须标识 Serializable 特性。如果是定义DataContract的话,一样是要在定义的实体类上加上一堆特性的。
    更加麻烦。建议楼主创建个基类,所有实体类都继承于基类,基类标识 Serializable 特性就行了。附上 DataContract 示例(来自msdn):namespace DataContractSerializerExample
    {
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.Runtime.Serialization;
        using System.Xml;    // You must apply a DataContractAttribute or SerializableAttribute
        // to a class to have it serialized by the DataContractSerializer.
        [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")]
        class Person : IExtensibleDataObject
        {
            [DataMember()]
            public string FirstName;
            [DataMember]
            public string LastName;
            [DataMember()]
            public int ID;        public Person(string newfName, string newLName, int newID)
            {
                FirstName = newfName;
                LastName = newLName;
                ID = newID;
            }        private ExtensionDataObject extensionData_Value;        public ExtensionDataObject ExtensionData
            {
                get
                {
                    return extensionData_Value;
                }
                set
                {
                    extensionData_Value = value;
                }
            }
        }    public sealed class Test
        {
            private Test() { }        public static void Main()
            {
                try
                {
                    WriteObject("DataContractSerializerExample.xml");
                    ReadObject("DataContractSerializerExample.xml");            }            catch (SerializationException serExc)
                {
                    Console.WriteLine("Serialization Failed");
                    Console.WriteLine(serExc.Message);
                }
                catch (Exception exc)
                {
                    Console.WriteLine(
                    "The serialization operation failed: {0} StackTrace: {1}",
                    exc.Message, exc.StackTrace);
                }            finally
                {
                    Console.WriteLine("Press <Enter> to exit....");
                    Console.ReadLine();
                }
            }        public static void WriteObject(string fileName)
            {
                Console.WriteLine(
                    "Creating a Person object and serializing it.");
                Person p1 = new Person("Zighetti", "Barbara", 101);
                FileStream writer = new FileStream(fileName, FileMode.Create);
                DataContractSerializer ser =
                    new DataContractSerializer(typeof(Person));
                ser.WriteObject(writer, p1);
                writer.Close();
            }        public static void ReadObject(string fileName)
            {
                Console.WriteLine("Deserializing an instance of the object.");
                FileStream fs = new FileStream(fileName,
                FileMode.Open);
                XmlDictionaryReader reader =
                    XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
                DataContractSerializer ser = new DataContractSerializer(typeof(Person));            // Deserialize the data and read it from the instance.
                Person deserializedPerson =
                    (Person)ser.ReadObject(reader, true);
                reader.Close();
                fs.Close();
                Console.WriteLine(String.Format("{0} {1}, ID: {2}",
                deserializedPerson.FirstName, deserializedPerson.LastName,
                deserializedPerson.ID));
            }
        }
      

  5.   

    回9楼 我的自定义实体类都加的有数据契约的特性标识,但没有加Serializable这个标识,因为我的这个项目比较特殊,是一个Silverlight项目,他只认DataContract不认Serializable,我在去用DataContractSerializer ser = new DataContractSerializer(typeof(Person));这段代码的时候,是不知道Person这个类型的,大概是这样的
    DataContractSerializer ser = new DataContractSerializer(typeof(Dictionary<string,object>));object可能是一个person也可能是其它的自定义类
      

  6.   

    你这么说,明白了。单看msdn,我觉得不是object出问题了(你存放在Dictionary里的对象都是标识过DataContract的不是吗?)是 Dictionary 不知道 object 的类型。在构造 DataContractSerializer 的时候,把所有用到Type都加进去就好了。例如:List<Type> knownTypes = new List<Type>();
    knownTypes.Add(typeof(Person));
     
    DataContractSerializer ser =
                    new DataContractSerializer(typeof(Dictionary<string, Person>), knownTypes);
      

  7.   

    如果不知道object类型的话,可以用反射把你项目里的所有DataContract特性的对象类型都反射出来放到一个静态List里。
      

  8.   

    我想多了!如果不知道object类型的话,在序列化前遍历Dictionary,弄出个Type List就好了。
      

  9.   


    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Text;
    using System.IO;
    using System.Runtime.Serialization;namespace KnownTypeAttributeExample
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    TestClass tc = new TestClass() { ID = "123", Name = "abc" };
                    Dictionary<string, TestClass> dict = new Dictionary<string, TestClass>();
                    dict.Add("test", tc);                List<Type> knownTypes = new List<Type>();
                    knownTypes.Add(typeof(TestClass));                Serialize<Dictionary<string, TestClass>>("D:\\KnownTypeAttributeExample.xml", knownTypes, dict);
                    Dictionary<string, TestClass> dict2 = Deserialize<Dictionary<string, TestClass>>("D:\\KnownTypeAttributeExample.xml", knownTypes);                TestClass tc2 = dict2["test"];
                    Console.WriteLine("ID:{0} Name:{1}", tc2.ID, tc2.Name);
                }
                catch (SerializationException exc)
                {
                    Console.WriteLine("{0}: {1}", exc.Message,
                        exc.StackTrace);
                }
                finally
                {
                    Console.WriteLine("Press Enter to exit...");
                    Console.ReadLine();
                }
            }        public static void Serialize<T>(string path, List<Type> knownTypes, T t)
            {
                DataContractSerializer ser =
                    new DataContractSerializer(typeof(T), knownTypes);            FileStream fs = new FileStream(path, FileMode.Create);
                using (fs)
                {
                    ser.WriteObject(fs, t);
                }
            }        public static T Deserialize<T>(string path, List<Type> knownTypes)
            {
                DataContractSerializer ser =
                    new DataContractSerializer(typeof(T), knownTypes);
                FileStream fs = new FileStream(path, FileMode.Open);
                T obj = default(T);
                using (fs)
                {
                    obj = (T)ser.ReadObject(fs);
                }
                return obj;
            }        [DataContract]
            public class TestClass
            {
                [DataMember]
                public string Name { get; set; }
                [DataMember]
                public string ID { get; set; }
            }       
        }
    }
      

  10.   


    这样更好,object 都可以序列化。
    object result = my.Invoke(this, parameters, out outArgs);
    byte[] items = Compress(result);public static byte[] Serialize<T>(T data)
            {
                byte[] result = null;
                using (MemoryStream memory = new MemoryStream())
                {
                    DataContractSerializer ser = new DataContractSerializer(typeof(T));                using (XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(memory))
                    {
                        ser.WriteObject(binaryDictionaryWriter, data);
                        binaryDictionaryWriter.Flush();
                    }
                    byte[] array = memory.ToArray();            }
                return result;
            }