Como dizer ao Json.Net globalmente para aplicar o StringEnumConverter a todos os enums

84

Desejo desserializar as enumerações para sua representação de string e vice-versa com json.net. A única maneira que eu poderia descobrir para dizer ao framework para aplicá-lo StringEnumConverteré anotar as propriedades em questão assim:

[JsonConverter(typeof(StringEnumConverter))]
public virtual MyEnums MyEnum { get; set; }

No entanto, no meu caso de uso, seria muito mais conveniente configurar o json.net globalmente de forma que todas as enumerações sejam (des) serializadas usando o StringEnumConverter, sem a necessidade de anotações extras.

Existe alguma maneira de fazer isso, por exemplo, com a ajuda de custom JsonSerializerSettings?

Leo
fonte

Respostas:

113

Adicione um StringEnumConverterà JsonSerializerSettingscoleção Conversores.

Documentação: serializar com JsonConverters


Se quiser que o serializador use camelCasing, você também pode definir isso:

SerializerSettings.Converters.Add(
    new StringEnumConverter { CamelCaseText = true });

Isso será serializado SomeValuepara someValue.

James Newton-King
fonte
Tentei definir isso no meu global.asax.cs, GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettingsmas não funcionou. Alguma ideia de por que isso poderia ser?
amed
Existe alguma maneira de minúsculas no nome do campo? O sinalizador CamelCaseText é embutido em código na classe e não vejo uma maneira de usar uma estratégia de capitalização diferente.
mikebridge,
@mikebridge Você encontrou uma solução para isso? Também estou procurando uma maneira de definir o nome de cada opção de enum sozinho (ou usar letras minúsculas).
Timm
1
@Timm Sim, usei este post: stackoverflow.com/questions/6288660/…
mikebridge
@mikebridge Obrigado. Descobri que [EnumMember (Value = "undefined")] por entrada de enum também funciona bem com JSON.Net (embora não seja compatível com o desserializador JSON da Microsoft)
Timm
40

As outras respostas funcionam para ASP.NET, mas se você deseja definir essas configurações geralmente para chamar JsonConvert em qualquer contexto, você pode fazer:

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

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

Gaz
fonte
2
O que eu estava procurando! Ainda mais curto:JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Converters = { new StringEnumConverter { CamelCaseText = true } } };
Kapé
Você me salvou! Obrigado mano! gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
paqogomez
18

No seu Global.asax.cs adicione

HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add
                (new Newtonsoft.Json.Converters.StringEnumConverter());
Iggy
fonte
Esta solução parece funcionar perfeitamente para serialização WebAPI. Obrigado!
charlie
5

Para ASP.NET Core 2, faça o seguinte:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
                .AddJsonOptions(options =>
                {
                    options.SerializerSettings.Converters.Add(new StringEnumConverter());
                });

        ...

Observe que não services.AddJsonOptions(...), ele deve ser marcado no MVC porque você está criando configurações para o MVC.

Simon_Weaver
fonte