2012-04-20 27 views
0

我不知道如何通過DataContractSerialize序列化對象。 這裏是我的代碼:爲什麼DataContractSerializer不起作用?

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

什麼是例外? – mgnoonan 2012-04-20 01:08:50

+0

它需要KnowType 類型'System.RuntimeType'與數據協定名稱'RuntimeType:http://schemas.datacontract.org/2004/07/System'不是預期的。將任何未知的靜態類型添加到已知類型列表中 - 例如,使用KnownTypeAttribute屬性或將它們添加到傳遞給DataContractSerializer的已知類型列表中。 – GeminiYellow 2012-04-20 01:11:44

回答

0

首先,你不能有一個類型是[Serializable]和[DataContract]。這不被推薦,是毫無意義的。只需要[DataContract]。有關原因的更多信息,請參見this post on the data contract programming model

無論如何,這裏的問題是你實際上試圖序列化一個RuntimeType,因爲MessageType被表示爲一個RuntimeType。 RuntimeType是一個內部類,它是Type的子類,並且不是公有的,所以你不能有意將它稱爲已知類型。請參閱What's the difference between System.Type and System.RuntimeType in C#?以獲取有關RuntimeType是什麼以及它爲什麼的更多信息。

所以,你這裏有兩種選擇:

  • 考慮添加KnownTypes屬性,需要一個靜態方法名。從你的靜態方法中,你可以返回你真正想要的各種類型,包括如果你使用反射可能的RuntimeType。

  • 我最好的選擇建議是讓消息類型類型句柄一(一的RuntimeTypeHandle)。這樣做的好處是,你實際上可以使RuntimeTyepHandle一個已知的類型,因爲它是公衆。它也像其他類型一樣是可序列化和反序列化的。關於我的意思,請參閱this excellent blog post

+0

感謝您的幫助,它爲我工作。 – GeminiYellow 2012-05-08 00:00:24