0

我不知道如何通过 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);

它会抛出异常。我能做些什么?

4

1 回答 1

0

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.

于 2012-04-26T15:53:26.243 回答