I don't know how to Serialize a object by DataContractSerialize. Here is my code:
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());
}
}
and entity
[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
}
When I run the DataContractSerialize like this:
var sData = SerializerHelper.DataContractSerialize(msg);
it will throw a exception. What can I do?
First, you cannot have a type that is both [Serializable] and [DataContract]. This is not recommended and is meaningless. Just have [DataContract]. For more information on why, see this post on the data contract programming model.
Anyway, the problem here is that you're actually trying to serialize a RuntimeType, because MessageType is represented as a RuntimeType. RuntimeType is an internal class that's a child of Type and that is not public, so that you can't knowingly refer to it as a known type. See What's the difference between System.Type and System.RuntimeType in C#? for more information on what RuntimeType is and why it is the way it is.
So, you have two options here:
Consider adding a KnownTypes attribute that takes a static method name. From your static method, you can return the various types you really want, including potentially RuntimeType if you use reflection.
The option I'd recommend is to make MessageType a TypeHandle (a RuntimeTypeHandle.) The advantage of this is that you can actually make RuntimeTyepHandle a known type since it's public. It's also serializable and deserializable just like any other type. See this excellent blog post on what I mean.