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"}
, что и ожидалось.
Ответы
Ответ 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 для сериализации, иначе он просто использует сериализатор по умолчанию.