Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET StringEnumConverter not working as expected

I'm attempting to use Json.NET with the System.Net.Http.HttpClient to send an object with an enum property, however the enum is always serialized as an integer value rather than the string equivalent.

I've tried following the instructions here:

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

By both adding an instance of StringEnumConverter to the JsonSerializerSettings and also tried to decorate the enum property with [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] neither of which appear to be working in my example.

I'm using Json.NET version 5.0.8

Can anyone tell me what I'm doing wrong please? Here is a sample console app to replicate showing both the global serializer settings and the decorated property:

Thanks.

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
        }
    }
}

I've inspected this with Fiddler and it posts: {"Enum":0} rather than {"Enum":"Hello"} which is what I would expect.

like image 850
Garry Marsland Avatar asked Nov 01 '13 16:11

Garry Marsland


2 Answers

The ItemConverterType property of the JsonPropertyAttribute attribute is the converter to use for items of a collection. You should be using the JsonConverterAttribute attribute.

public class TestData
{
    [JsonConverter(typeof(StringEnumConverter))]
    public TestEnum Enum { get; set; }
}
like image 159
Jeff Mercado Avatar answered Sep 19 '22 11:09

Jeff Mercado


I think I've found a way of getting it to work without decorating attributes. It involves replacing client.PostAsJsonAsync() with client.PostAsync(). You can then specify the MediaTypeFormatter to use which in this case will be the JsonMediaTypeFormatter.

Source here: .net HttpClient with custom JsonConverter

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

This still doesn't explain why the DefaultSettings aren't being applied. I can only assume that the presence of the [JsonConverter] property forces the HttpClient to use Json.NET for serialization, otherwise it just uses the default serializer.

like image 39
Garry Marsland Avatar answered Sep 19 '22 11:09

Garry Marsland