Como definir globalmente as opções padrão para System.Text.Json.JsonSerializer?

12

ATUALIZAÇÃO [2019-12-23]: em parte devido à contribuição da comunidade vocal , esse problema foi adicionado ao roteiro do .NET 5.0.

UPDATE [2019-10-10]: se estiver interessado em ver esse comportamento implementado paraSystem.Text.Json.JsonSerializervá para a edição aberta do GitHub, apontada por Chris Yungmann, e pesa.


Em vez disso:

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};
JsonSerializer.Deserialize<SomeObject>(someJsonString, options);

Eu gostaria de fazer algo assim:

// This property is a pleasant fiction
JsonSerializer.DefaultSettings = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};

// This uses my options
JsonSerializer.Deserialize<SomeObject>(someJsonString); 

// And somewhere else in the same codebase...
// This also uses my options
JsonSerializer.Deserialize<SomeOtherObject>(someOtherJsonString); 

A esperança é não ter que passar uma instância dos casos JsonSerializerOptionsmais comuns e substituir a exceção, não a regra.

Conforme indicado nestas perguntas e respostas , esse é um recurso útil do Json.Net. Olhei na documentação para o System.Text.Jsonbem como este repo GitHub for .NET Core. E esse aqui .

Parece não haver um analógico para gerenciar padrões de serialização JSON no .NET Core 3. Ou estou ignorando isso?

Trevor Reid
fonte
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3- você está falando sobre solicitações de entrada e saída da sua API? ou solicitações e respostas a outros recursos?
Ps2goat 10/10/19
@ ps2goat Não sei se entendi sua pergunta. O problema aqui é (des) serializar seqüências JSON. Eles podem vir de qualquer número de fontes.
Trevor Reid
Eu estava perguntando porque há lugares especiais durante a inicialização para formatadores de entrada e saída (por exemplo, para a ligação do modelo)
ps2goat
Ah, entendi. Nesse sentido, acho que nosso caso se enquadra em "outros recursos". @ ps2goat
Trevor Reid
É realmente triste, até o .net core 3.1, ainda não havia um bom serializador json embutido.
Piada Huang

Respostas:

4

Não, JsonSerializerOptionsnão expõe as opções padrão . Se você estiver usando uma estrutura da web específica, pode haver uma maneira de especificar as configurações de (des) serialização por meio disso. Caso contrário, sugiro criar seus próprios métodos de conveniência.

Veja também esta edição em aberto .

Chris Yungmann
fonte
3

Você pode criar um método de extensão. Aqui está um exemplo

Eu uso métodos separados versus ter que criar configurações especiais, para que todas as configurações fiquem em um único local e facilmente reutilizáveis.

public static class DeserializeExtensions
{
    private static JsonSerializerOptions defaultSerializerSettings = new JsonSerializerOptions();

    // set this up how you need to!
    private static JsonSerializerOptions featureXSerializerSettings = new JsonSerializerOptions();


    public static T Deserialize<T>(this string json)
    {       
        return JsonSerializer.Deserialize<T>(json, defaultSerializerSettings);
    }

    public static T DeserializeCustom<T>(this string json, JsonSerializerOptions settings)
    {
        return JsonSerializer.Deserialize<T>(json, settings);
    }

    public static T DeserializeFeatureX<T>(this string json)
    {
        return JsonSerializer.Deserialize<T>(json, featureXSerializerSettings);
    }
}

Em seguida, você o chama como um método em uma string, seja literal ou variável.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();
ps2goat
fonte
Ah, a sua é outra resposta dependente do Json.Net, eu acho. Esta pergunta é sobre o System.Text.Json.JsonSerializerNET Core-3.0 sem dependências adicionais. Obrigado.
Trevor Reid
2
Essa é a beleza da abstração. Nenhum código é alterado fora desta classe de extensão! Acabei de atualizar para o incorporado System.Text.Json.JsonSerializer. O conceito era exatamente o mesmo. Também atualizei o link de exemplo.
Ps2goat 10/10/19
2

Uma solução alternativa foi proposta pelo usuário do GitHub andre-ss6 da seguinte maneira:

((JsonSerializerOptions)typeof(JsonSerializerOptions)
    .GetField("s_defaultOptions", 
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.NonPublic).GetValue(null))
    .PropertyNameCaseInsensitive = true;
Trevor Reid
fonte
-1

(Se você mudar para o Json.NET)

Prefiro e recomendo ser explícito e passar configurações para todas as chamadas, mas você pode definir padrões com DefaultSettings .

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

e depois

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
timtim
fonte
Esta resposta e link de @tymtam se aplicam ao Json.Net. A pergunta refere-se ao comportamento similar no System.Text.Jsonqual a serialização JSON é inserida no .NET Core 3.0. Obrigado por tomar o tempo para responder.
Trevor Reid