Beim Deserialisieren einer gekennzeichneten Enumeration, die mit einem EnumMemberAttribute mit einem Wert versehen ist, der ein Leerzeichen enthält, wird eine SerializationException ausgelöst. Das Leerzeichen im Wert wird als Trennzeichen behandelt.Das Deserialisieren einer gekennzeichneten Enumeration mit einem Leerzeichen führt zu SerializationException
Gibt es eine Möglichkeit, das Trennzeichen zu ändern oder die Werte in Anführungszeichen zu setzen? Oder gibt es sogar eine einfachere Lösung?
Optionen Ich bin schon in Betracht ziehen:
- Ersetzen des markierten Enum mit einer Liste dieser Aufzählungstyp
- Ersetzen der Räume mit Unterstrichen
- Dieses in einem WCF-Dienst verwendet wird, und ich bin bewusst, dass enums in datacontracts von einigen als eine schlechte Sache betrachtet werden. Also denke ich auch darüber nach, die Enum alle zusammen zu verlieren.
Aber ich fühle wirklich, dass dies etwas konfigurierbar sein sollte oder etwas, das andere Leute bereits gelöst haben. Aber ich kann nichts finden.
Ich habe das Problem auf einen einfachen Komponententest gekocht. Der folgende Code ergibt:
Message = Ungültige Enum-Wert '-Test' kann nicht deserialisiert in Typ 'UnitTests.TestEnum' werden. Stellen Sie sicher, dass die erforderlichen Enum-Werte vorhanden sind und mit dem EnumMemberAttribute-Attribut gekennzeichnet sind, wenn der Typ über das DataContractAttribute-Attribut verfügt. 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,
}
}
Ich würde nicht sagen, dass „Aufzählungen in Datacontracts eine schlechte Sache sind“, aber für mich „die Verwendung von Leerzeichen in Aufzählungen ist eine schlechte Sache“ ;-) – fixagon
Vereinbarte :) Ich mag keine Leerzeichen überall, aber das ist nicht meine Wahl . Wenn ich dir die Werte zeigen würde, die in den tatsächlichen enums gehen müssen, würdest du anfangen zu weinen. – KeesDijk
schau dir das auch an: http://stackoverflow.com/questions/1415140/can-my-enums-have-friendly-names, hilft aber nicht wirklich in deiner Situation. Andernfalls können Sie die Enumeration einfach als int serialisieren. aber das bricht den Datenkontrakt – fixagon