我不知道如何通过DataContractSerialize序列化对象。 这是我的代码:
public static string DataContractSerialize(object target)
{
var formatter = new DataContractSerializer(target.GetType());
using (var stream = new MemoryStream())
{
formatter.WriteObject(stream, target);
stream.Position = 0;
return Encoding.UTF8.GetString(stream.ToArray());
}
}
和实体
[Serializable, DataContract(Namespace = "CommunicationModel.Entity")]
[KnownType(typeof(Message))]
[KnownType(typeof(int))]
[KnownType(typeof(string))]
[KnownType(typeof(Type))]
[KnownType(typeof(object))]
public class Message : IDisposable
{
public Message(string stringInfo)
{
MessageValue = stringInfo;
MessageType = typeof (string);
}
public Message(int intInfo)
{
MessageValue = intInfo;
MessageType = typeof (int);
}
[DataMember]
public Type MessageType { get; private set; }
[DataMember]
public object MessageValue { get; private set; }
#region Implementation of IDisposable
public void Dispose()
{
}
#endregion
}
当我像这样运行DataContractSerialize时:
var sData = SerializerHelper.DataContractSerialize(msg);
它会引发异常。我该怎么办?
答案 0 :(得分:0)
首先,您不能拥有[Serializable]和[DataContract]的类型。这是不推荐的,没有意义。只需要[DataContract]。有关原因的详细信息,请参阅this post on the data contract programming model。
无论如何,这里的问题是你实际上是在尝试序列化RuntimeType,因为MessageType被表示为RuntimeType。 RuntimeType是一个内部类,它是Type的子类,并且不是公共的,因此您无法有意将其称为已知类型。有关RuntimeType是什么以及它的原因,请参阅What's the difference between System.Type and System.RuntimeType in C#?。
所以,你有两个选择:
考虑添加一个采用静态方法名称的KnownTypes属性。从静态方法中,您可以返回您真正想要的各种类型,包括使用反射时可能的RuntimeType。
我推荐的选项是使MessageType成为一个TypeHandle(一个RuntimeTypeHandle。)这样做的好处是你可以让RuntimeTyepHandle成为一个已知的类型,因为它是公共的。它也可以像任何其他类型一样进行序列化和反序列化。请参阅this excellent blog post我的意思。