Как настроить десериализацию перечисления JSON в .NET?

У меня есть следующий пример кода 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 на перечисления пользовательских дескрипторов? Или, может быть, есть лучший способ сделать это?

8
задан Ajay 14 February 2017 в 07:00
поделиться