J'ai deux contrôleurs de contrôleur: ControllerA
et ControllerB
. La classe de base de chaque contrôleur est Controller
.
ControllerA
doit retourner JSON dans le format par défaut (camelCase). ControllerB
doit renvoyer des données dans un format JSON différent: snake_case.
Comment puis-je implémenter cela dans ASP.NET Core 2.1?
J'ai essayé le startup
avec:
services
.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new StringEnumConverter());
options.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
})
.AddControllersAsServices();
Mais cela changera la sérialisation pour les contrôleurs tous, pas seulement pour ControllerB
. Comment puis-je configurer ou annoter cette fonction pour 1 contrôleur?
Vous pouvez y parvenir avec une combinaison d'un Action Filter et d'un Output Formatter . Voici un exemple de ce à quoi pourrait ressembler le filtre d'action:
public class SnakeCaseAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext ctx)
{
if (ctx.Result is ObjectResult objectResult)
{
objectResult.Formatters.Add(new JsonOutputFormatter(
new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
},
ctx.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>()));
}
}
}
En utilisant OnActionExecuted
, le code s'exécute après l'action correspondante et vérifie d'abord si le résultat est un ObjectResult
(qui s'applique également à OkObjectResult
grâce à l'héritage). S'il s'agit d'un ObjectResult
, le filtre ajoute simplement une version personnalisée d'un JsonOutputFormatter
qui sérialisera les propriétés à l'aide de SnakeCaseNamingStrategy
. Le deuxième paramètre du constructeur JsonOutputFormatter
est extrait du conteneur DI.
Pour utiliser ce filtre, appliquez-le simplement au contrôleur approprié:
[SnakeCase]
public class ControllerB : Controller { }
Remarque: Vous voudrez peut-être créer le JsonOutputFormatter
à l'avance quelque part, par exemple - je ne suis pas allé aussi loin dans l'exemple car c'est secondaire à la question à portée de main.