Po odfałszowaniu oznaczonego enum, które jest ozdobione atrybutem EnumMemberAttribute z wartością zawierającą spację, generowany jest wyjątek SerializationException. Przestrzeń w wartości jest traktowana jako separator.Odsumerowanie oznaczonego enum z spacją powoduje SerializationException
Czy istnieje sposób na zmianę separatora lub umieszczenie wartości w cudzysłowach? Czy istnieje nawet bardziej proste rozwiązanie?
Opcje ja już rozważam to:
- Wymiana oznaczonej enum z listy tego typu Enum
- Wymiana spacje podkreślenia
- ta jest wykorzystywana w usług WCF, a ja am świadomy, że wyliczenia w datacontracts przez niektórych są uważane za złe. Więc także myślę o utracie enum wszystko razem.
Ale naprawdę uważam, że powinno to być coś konfigurowalnego lub coś, co inni już rozwiązali. Ale nie mogę znaleźć niczego.
Ugotowałem ten problem w prosty test jednostkowy. Poniższy kod powoduje:
Message = Nieprawidłowa wartość enum 'test' nie może być rozszeregować do typu 'UnitTests.TestEnum'. Upewnij się, że niezbędne wartości wyliczeniowe są obecne i są oznaczone atrybutem EnumMemberAttribute, jeśli typ ma atrybut DataContractAttribute. Source = System.Runtime.Serialization
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests
{
[TestClass]
public class EnumSerizalizationTests
{
[TestMethod]
public void SerializingAndDesrializingAFlaggedEnumShouldResultInSameEnumValues()
{
//Arrange
var orgObject = new TestClass { Value = TestEnum.TestValue1 | TestEnum.TestValue2 };
//Act
var temp = DataContractSerializeObject(orgObject);
var newObject = DataContractDeSerializeObject<TestClass>(temp);
//Assert
newObject.ShouldBeEquivalentTo(orgObject, "Roundtripping serialization should result in same value");
}
public string DataContractSerializeObject<T>(T objectToSerialize)
{
using (var output = new StringWriter())
{
using (var writer = new XmlTextWriter(output) {Formatting = Formatting.Indented})
{
new DataContractSerializer(typeof (T)).WriteObject(writer, objectToSerialize);
return output.GetStringBuilder().ToString();
}
}
}
public T DataContractDeSerializeObject<T>(string stringToDeSerialize)
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
T result;
using (StringReader stringReader = new StringReader(stringToDeSerialize))
{
using (XmlReader xmlReader = XmlReader.Create(stringReader))
{
result = (T)ser.ReadObject(xmlReader);
}
}
return result;
}
}
[DataContract]
[KnownType(typeof(TestEnum))]
public class TestClass
{
[DataMember]
public TestEnum Value { get; set; }
}
[Flags]
[DataContract]
public enum TestEnum
{
[EnumMember(Value = "Test value one")]
TestValue1 = 1,
[EnumMember(Value = "Test value two")]
TestValue2 = 2,
[EnumMember]
TestValue3 = 4,
[EnumMember]
TestValue4 = 8,
}
}
Nie powiedziałbym, że "wyliczenia w datacontracts są złe", ale dla mnie "używanie spacji w enumach to zła rzecz" ;-) – fixagon
Uzgodnione :) Nie lubię spacji gdziekolwiek, ale to nie jest mój wybór . Gdybym pokazał ci wartości, które muszą znaleźć się w rzeczywistych podsumowaniach, zacząłbyś płakać. – KeesDijk
spójrz także na to: http://stackoverflow.com/questions/1415140/can-my-enums-have-friendly-names, ale tak naprawdę nie pomaga w twojej sytuacji. w przeciwnym razie możesz po prostu serializować enum jako int. ale to niszczy datacontract – fixagon