2011-04-07 89 views
1

考慮下面的代碼設置,C#的DataContractSerializer SerializationException與枚舉對象場

[DataContract] 
public class TestClass 
{ 
    [DataMember] 
    public object _TestVariable; 

    public TestClass(object value) 
    { 
    _TestVariable = value; 
    } 

    public void Save() 
    { 
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(new FileStream("test.tmp", FileMode.Create))) 
    { 
     DataContractSerializer ser = new DataContractSerializer(typeof(TestClass)); 
     ser.WriteObject(writer, this); 
    } 
    } 
} 

public enum MyEnum 
{ 
    One, 
    Two, 
    Three 
} 

爲什麼會失敗時_TestVariable設置爲枚舉值序列化?

new TestClass(1).Save(); // Works 
new TestClass("asdfqwer").Save(); // Works 
new TestClass(DateTime.UtcNow).Save(); // Works 
new TestClass(MyEnum.One).Save(); // Fails 

引發的異常是:

System.Runtime.Serialization.SerializationException : Type 'xxx.MyEnum' with data contract name 'xxx.MyEnum:http://schemas.datacontract.org/2004/07/Tests' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. 
+1

你試圖通過使用_TestVariable對象類型來解決什麼問題,也許你可以解釋真正的問題。 – 2011-04-07 07:23:48

+0

請參閱類似問題的答案http://stackoverflow.com/a/8795410/52277 – 2013-05-29 18:11:54

回答

5

您應該在TestClass上使用KnownTypeAttribute

[DataContract] 
[KnownTypeAttribute(typeof(MyEnum))] 
public class TestClass 
+0

bingo不起作用!這使它編譯,但是是一個痛苦。不是枚舉簡單類型序列化? – mike 2011-04-07 07:33:50

+1

這不是關於枚舉。這是關於使用類型對象的變量而不是確切類型。在這種情況下,序列化程序不知道在序列化和反序列化過程中會遇到什麼類型,所以您應該通過此屬性來了解它。如果您使用的是精確數據類型而不是對象,則不需要此信息 – archil 2011-04-07 07:36:09

+0

好的,謝謝您的信息。 – mike 2011-04-07 07:37:36

0

MyEnum未標記爲可序列化。將DataContractAttribute添加到MyEnum應該可以解決它。

+0

如果我添加'[DataContract]到MyEnum – mike 2011-04-07 07:31:55

4

,你可以使用,以避免把KnownType屬性所有的地方是使用類型推演做的工作對你的另一個選擇。

class Program 
{ 
    static void Main(string[] args) 
    { 
     TestClass.Create(1).Save(); // Works 
     TestClass.Create("asdfqwer").Save(); // Works 
     TestClass.Create(DateTime.UtcNow).Save(); // Works 
     TestClass.Create(MyEnum.One).Save(); // Fails 
    } 
} 

public class TestClass 
{ 
    public static TestClass<T> Create<T>(T value) 
    { 
     return new TestClass<T>(value); 
    } 
} 

[DataContract] 
public class TestClass<T> 
{ 
    [DataMember] 
    public T _TestVariable; 

    public TestClass(T value) 
    { 
     _TestVariable = value; 
    } 

    public void Save() 
    { 
     using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(new MemoryStream())) 
     { 
      DataContractSerializer ser = new DataContractSerializer(typeof(TestClass<T>)); 
      ser.WriteObject(writer, this); 
     } 
    } 
} 

public enum MyEnum 
{ 
    One, 
    Two, 
    Three 
}