System.Net.Http.HttpClientでJson.NETを使用して、enumプロパティを持つオブジェクトを送信しようとしていますが、enumは常に、同等の文字列ではなく整数値としてシリアル化されます。
私はここの指示に従ってみました:
StringEnumConverterのインスタンスをJsonSerializerSettingsに追加することと、列挙型プロパティを[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"}
これは私が期待することです。
ItemConverterType
属性のJsonPropertyAttribute
プロパティは、コレクションのアイテムに使用するコンバーターです。 JsonConverterAttribute
属性を使用する必要があります。
public class TestData
{
[JsonConverter(typeof(StringEnumConverter))]
public TestEnum Enum { get; set; }
}
属性を装飾せずに動作させる方法を見つけたと思います。 client.PostAsJsonAsync()
をclient.PostAsync()
に置き換える必要があります。次に、使用するMediaTypeFormatterを指定できます。この場合はJsonMediaTypeFormatter
になります。
ここからのソース: カスタムJsonConverterを使用した.net HttpClient
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を使用するように強制されると想定できます。それ以外の場合は、デフォルトのシリアライザーを使用します。