2

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.
2
  • 1
    what problem are you trying to solve by using object type for _TestVariable, perhaps you could explain the real problem. Commented Apr 7, 2011 at 7:23
  • See the answer to a similar question stackoverflow.com/a/8795410/52277 Commented May 29, 2013 at 18:11

3 Answers 3

6

You should use KnownTypeAttribute on TestClass.

[DataContract]
[KnownTypeAttribute(typeof(MyEnum))]
public class TestClass
Sign up to request clarification or add additional context in comments.

2 Comments

bingo! this makes it compile, but is a pain. Aren't enums simple types to serialize?
That's not about enums. That's about using variable of type object instead of exact type. In this case, serializer has no knowledge about what type it will encounter during serialization and deserialization, so you should make it know via this attribute. If you used exact data type and not object, this whould not be needed
4

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
}

Comments

0

MyEnum is not marked as serializable. Adding DataContractAttribute to MyEnum should fix it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.