如何将一个Dictionary序列化成byte

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

请问怎样解决?
...全文
1251 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
lookmai 2011-04-09
  • 打赏
  • 举报
回复

这样更好,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;
}
机器人 2010-10-25
  • 打赏
  • 举报
回复

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


}
}

gamestar1 2010-10-25
  • 打赏
  • 举报
回复
谢谢楼上,明天试一下你的方法
机器人 2010-10-25
  • 打赏
  • 举报
回复
我想多了!如果不知道object类型的话,在序列化前遍历Dictionary,弄出个Type List就好了。
机器人 2010-10-25
  • 打赏
  • 举报
回复
如果不知道object类型的话,可以用反射把你项目里的所有DataContract特性的对象类型都反射出来放到一个静态List里。
机器人 2010-10-25
  • 打赏
  • 举报
回复
你这么说,明白了。

单看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);
gamestar1 2010-10-25
  • 打赏
  • 举报
回复
求助 up 顶
gamestar1 2010-10-25
  • 打赏
  • 举报
回复
回9楼 我的自定义实体类都加的有数据契约的特性标识,但没有加Serializable这个标识,因为我的这个项目比较特殊,是一个Silverlight项目,他只认DataContract不认Serializable,我在去用DataContractSerializer ser = new DataContractSerializer(typeof(Person));这段代码的时候,是不知道Person这个类型的,大概是这样的
DataContractSerializer ser = new DataContractSerializer(typeof(Dictionary<string,object>));object可能是一个person也可能是其它的自定义类
机器人 2010-10-25
  • 打赏
  • 举报
回复
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));
}
}


哥子谭 2010-10-25
  • 打赏
  • 举报
回复
自己写一个序列化的类
gamestar1 2010-10-25
  • 打赏
  • 举报
回复
求助 up 顶
gamestar1 2010-10-25
  • 打赏
  • 举报
回复
回4楼,我想实现一个这样的效果
我在数据库中建了一个二进制的字段,用来存放一些信息,在程序中将一个Dictionary<string,object>序列化成一个byte存到数据库中,取的时候在反序列化成一个字典类,而字典类中的value是一个object对象,有可能是我项目中的任何一个自定义实体类。
gamestar1 2010-10-25
  • 打赏
  • 举报
回复
2楼的方法我之前试过了,如果字典类中的value是一个string或int是没有任何问题的
但如果是一个实体类型,但这个类型是一个项目中自定义的类,例如Person或Employee可能就会出问题
guyehanxinlei 2010-10-25
  • 打赏
  • 举报
回复
不知道楼主想实现什么呢?
wuyq11 2010-10-25
  • 打赏
  • 举报
回复
key,value都是Serializable
wuyq11 2010-10-25
  • 打赏
  • 举报
回复
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);

ztenv 2010-10-25
  • 打赏
  • 举报
回复
不想加就手动转换吧,

111,105

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧