C # DataContractSerializer SerializationException с Enum, установленным в поле объекта - PullRequest
1 голос
/ 07 апреля 2011

Учитывая следующий код,

[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 задано значение Enum?

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.

Ответы [ 3 ]

5 голосов
/ 07 апреля 2011

Вы должны использовать KnownTypeAttribute в TestClass.

[DataContract]
[KnownTypeAttribute(typeof(MyEnum))]
public class TestClass
4 голосов
/ 09 декабря 2012

Еще один вариант, который вы можете использовать, чтобы избежать повсеместного использования атрибута 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
}
0 голосов
/ 07 апреля 2011

MyEnum не помечен как сериализуемый. Добавление DataContractAttribute в MyEnum должно исправить это.

...