Json.NET StringEnumConverter работает не так, как ожидалось - программирование
Подтвердить что ты не робот

Json.NET StringEnumConverter работает не так, как ожидалось

Я пытаюсь использовать Json.NET с System.Net.Http.HttpClient для отправки объекта с свойством enum, однако перечисление всегда сериализуется как целочисленное значение, а не эквивалент строки.

Я пробовал следующие инструкции:

http://james.newtonking.com/archive/2013/05/08/json-net-5-0-release-5-defaultsettings-and-extension-data

Добавив экземпляр StringEnumConverter в JsonSerializerSettings, а также попытался украсить свойство enum с помощью [JsonProperty(ItemConverterType = typeof(StringEnumConverter))], ни один из которых не работает в моем примере.

Я использую Json.NET версии 5.0.8

Может ли кто-нибудь сказать мне, что я делаю неправильно? Вот пример консольного приложения для репликации, показывающий как глобальные параметры сериализатора, так и украшенное свойство:

Спасибо.

using System;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient { BaseAddress = new Uri("http://test-uri.com") };

            JsonConvert.DefaultSettings = (() =>
            {
                var settings = new JsonSerializerSettings();
                settings.Converters.Add(new StringEnumConverter());
                return settings;
            });

            var data = new TestData { Enum = TestEnum.Hello };

            // The following posts: {"Enum":0}
            // Shouldn't it post {"Enum":"Hello"} instead?
            var result = client.PostAsJsonAsync("/test", data).Result;
        }

        public class TestData
        {
            [JsonProperty(ItemConverterType = typeof(StringEnumConverter))]
            public TestEnum Enum { get; set; }
        }

        public enum TestEnum
        {
            Hello,
            World
        }
    }
}

Я проверил это с помощью Fiddler, и он пишет: {"Enum":0} а не {"Enum":"Hello"}, что и ожидалось.

4b9b3361

Ответ 1

Свойством ItemConverterType атрибута JsonPropertyAttribute является конвертер, используемый для элементов коллекции. Вы должны использовать атрибут JsonConverterAttribute.

public class TestData
{
    [JsonConverter(typeof(StringEnumConverter))]
    public TestEnum Enum { get; set; }
}

Ответ 2

Я думаю, что нашел способ заставить его работать без украшения атрибутов. Он включает замену client.PostAsJsonAsync() на client.PostAsync(). Затем вы можете указать MediaTypeFormatter, который в этом случае будет JsonMediaTypeFormatter.

Источник здесь: .net HttpClient с пользовательским JsonConverter

    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new StringEnumConverter());
    var formatter = new JsonMediaTypeFormatter { SerializerSettings = settings };
    var response = client.PostAsync("/test", data, formatter).Result;

Это все еще не объясняет, почему DefaultSettings не применяются. Я могу только предположить, что наличие свойства [JsonConverter] заставляет HttpClient использовать Json.NET для сериализации, иначе он просто использует сериализатор по умолчанию.