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

まず、[Serializable]と[DataContract]の両方の型を持つことはできません。これは推奨されておらず、意味がありません。[DataContract]を持っているだけです。理由の詳細については、データコントラクトプログラミングモデルに関するこの投稿を参照してください。

とにかく、ここでの問題は、MessageTypeがRuntimeTypeとして表されるため、実際にRuntimeTypeをシリアル化しようとしていることです。RuntimeTypeは、Typeの子であり、パブリックではない内部クラスであるため、既知の型として故意に参照することはできません。C#のSystem.TypeとSystem.RuntimeTypeの違いは何ですか?を参照してください。RuntimeTypeとは何か、およびその理由について詳しくは、RuntimeTypeを参照してください。

したがって、ここには2つのオプションがあります。

  • 静的メソッド名をとるKnownTypes属性を追加することを検討してください。静的メソッドから、リフレクションを使用する場合はRuntimeTypeを含む、本当に必要なさまざまなタイプを返すことができます。

  • 私がお勧めするオプションは、MessageTypeをTypeHandle(RuntimeTypeHandle)にすることです。これの利点は、RuntimeTyepHandleがパブリックであるため、実際に既知の型にすることができることです。また、他のタイプと同じように、シリアル化および逆シリアル化できます。私の言いたいことについては、このすばらしいブログ投稿を参照してください。

于 2012-04-26T15:53:26.243 に答える