У меня есть следующий пример кода C #, который автоматически генерируется из xsd с помощью приложения svcutils.exe.
[DataContract]
public enum Foo
{
[EnumMember(Value = "bar")]
Bar = 1,
[EnumMember(Value = "baz")]
Baz = 2
}
[DataContract]
public class UNameIt
{
[DataMember(Name = "id")]
public long Id { get; private set; }
[DataMember(Name = "name")]
public string Name { get; private set; }
[DataMember(Name = "foo")]
public Foo Foo { get; private set; }
}
Ниже приведен модульный тест, который пытается десериализовать образец документа JSON вUNameIt класс.
[TestClass]
public class JsonSerializer_Fixture
{
public const string JsonData = @"{ ""id"":123456,
""name"":""John Doe"",
""foo"":""Bar""}";
[TestMethod]
public void DataObjectSimpleParseTest()
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UNameIt));
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(JsonData));
UNameIt dataObject = serializer.ReadObject(ms) as UNameIt;
Assert.IsNotNull(dataObject);
Assert.AreEqual(123456, dataObject.Id);
Assert.AreEqual(Foo.Baz, dataObject.Foo);
}
}
К сожалению, тест не пройден по следующей причине:
System.Runtime.Serialization.SerializationException: произошла ошибка десериализации объекта типа MyNamespace.Units.UNameIt,Значение 'Bar' не может быть проанализировано как тип 'Int64'.
Тест пройдет, если я обновлю свою строку JSON, чтобы заменить спецификатор строки для Enum на целое число, например
public const string JsonData = @"{ ""id"":123456,
""name"":""John Doe"",
""foo"":""1""}";
У меня нет гибкости для изменения поставляемого JSON, поэтому я должен выяснить, как преобразовать строковое представление Enum, возможно, при сериализации.В идеале, я хотел бы облегчить это, не меняя свой класс для автоматического создания, потому что, как только я заново сгенерирую класс, я потеряю свои изменения.
Мне интересно, можно ли было бы расширить DataContractJsonSerializer для пользовательской обработки перечислений?Или, может быть, есть лучший способ сделать это?