¿Cómo establecer globalmente las opciones predeterminadas para System.Text.Json.JsonSerializer?

12

ACTUALIZACIÓN [2019-12-23]: Debido en parte a la opinión de la comunidad vocal , este problema se ha agregado a la hoja de ruta para .NET 5.0.

ACTUALIZACIÓN [2019-10-10]: si está interesado en ver este comportamiento implementado paraSystem.Text.Json.JsonSerializerdiríjase al tema abierto de GitHub señalado por Chris Yungmann y evalúe .


En lugar de esto:

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

Me gustaría hacer algo como esto:

// 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); 

La esperanza es no tener que pasar una instancia de JsonSerializerOptionsnuestros casos más comunes, y anular la excepción, no la regla.

Como se indica en estas preguntas y respuestas, esta es una característica útil de Json.Net. Miré en la documentación para el System.Text.Json, así como la cesión temporal de GitHub para .NET Core. Y éste .

No parece haber un análogo para administrar los valores predeterminados de serialización JSON en .NET Core 3. ¿O lo estoy pasando por alto?

Trevor Reid
fuente
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3- ¿Estás hablando de solicitudes dentro y fuera de tu API? o solicitudes y respuestas a otros recursos?
ps2goat
@ ps2goat No estoy seguro de entender tu pregunta. El asunto aquí es (des) serializar cadenas JSON. Podrían provenir de cualquier cantidad de fuentes.
Trevor Reid
Estaba preguntando porque hay lugares especiales durante el inicio para los formateadores de entrada y salida (por ejemplo, para el enlace del modelo)
ps2goat
Ah, te tengo. En ese sentido, creo que nuestro caso recaería en "otros recursos". @ ps2goat
Trevor Reid
Es realmente triste, hasta .net core 3.1, todavía no había un buen serializador json incorporado.
Broma Huang

Respuestas:

4

No, JsonSerializerOptionsno expone las opciones predeterminadas . Si está utilizando un marco web particular, puede haber una manera de especificar la configuración de (des) serialización a través de eso. De lo contrario, sugiero crear sus propios métodos de conveniencia.

Vea también este tema abierto .

Chris Yungmann
fuente
3

Puedes crear un método de extensión. Aquí hay un ejemplo

Utilizo métodos separados frente a tener que crear configuraciones especiales, para que todas las configuraciones estén en un solo lugar y sean fácilmente reutilizables.

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

Luego lo llama como un método en una cadena, ya sea literal o una variable.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();
ps2goat
fuente
Ah, creo que la suya es otra respuesta dependiente de Json.Net. Esta pregunta es sobre System.Text.Json.JsonSerializerin NET Core-3.0 sin dependencias adicionales. Gracias.
Trevor Reid
2
Esa es la belleza de la abstracción. ¡Ningún código cambia fuera de esta clase de extensión! Acabo de actualizar a la incorporada System.Text.Json.JsonSerializer. El concepto era exactamente el mismo. También actualicé el enlace de ejemplo.
ps2goat
3

Las opciones predeterminadas no están expuestas en JsonSerializer.NET Core 3.1. Sin embargo, a partir de diciembre de 2019, esto se ha agregado a la hoja de ruta para 5.0.

El lanzamiento de .NET 5.0 se espera para noviembre de 2020. Pero no hay garantía de que este problema en particular se aborde en un momento determinado. Además de esperar, estas respuestas sugieren soluciones alternativas:

Trevor Reid
fuente
2

El usuario de GitHub andre-ss6 ha propuesto una solución alternativa de la siguiente manera:

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

(Si alguna vez cambia a usar Json.NET)

Prefiero y recomiendo ser explícito y pasar la configuración a todas las llamadas, pero puede establecer valores predeterminados con DefaultSettings .

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

y entonces

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
tymtam
fuente
Esta respuesta y enlace de @tymtam se aplica a Json.Net. La pregunta se refiere al comportamiento similar en el System.Text.Jsonque la serialización JSON está integrada en .NET Core 3.0. Gracias por tomarse el tiempo de responder.
Trevor Reid