C# DataContractSerializer SerializationException with Enum set in object field
Given the following code,
[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
}
Why does it fail to serialize when _TestVariable
is set to an Enum value?
new TestClass(1).Save(); // Works
new TestClass("asdfqwer").Save(); // Works
new TestClass(DateTime.UtcNow).Save(); // Works
new TestClass(MyEnum.One).Save(); // Fails
The exception thrown is:
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.
You should use KnownTypeAttribute on TestClass.
[DataContract]
[KnownTypeAttribute(typeof(MyEnum))]
public class TestClass
Another option that you could employ to avoid having to put the KnownType attribute all over the place is to use type deduction to do the work for you.
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
}
MyEnum is not marked as serializable. Adding DataContractAttribute to MyEnum should fix it.
精彩评论