Configurer les formateurs d’entrée / sortie sur les contrôleurs avec ASP.NET Core 2.1

Je suis en train de réécrire un ancien projet ASP.NET WebAPI 2.1 vers ASP.NET Core MVC 2.1. L’un des problèmes auquel je suis confronté concerne le portage de l’ancien comportement du service, qui configure les formateurs d’entrée et de sortie via des atsortingbuts personnalisés qui implémentent l’interface IControllerConfiguration. Je n’ai pas été en mesure de trouver un remplaçant pour cette interface, ni d’alternative pour configurer les formateurs sur une base contrôleur, à part les injecter au niveau global avec la méthode AddMvc (options).

Je n’ai rien trouvé qui puisse être configuré au niveau du contrôleur, mais j’ai trouvé une solution qui implique des modifications à chaque action nécessitant cette fonctionnalité. Dans mon cas, j’avais besoin de personnaliser les parameters du sérialiseur JSON, ce qui peut être fait comme ceci pour la sortie:

[HttpGet] public IActionResult Get() { ... return Json(result, _serializerSettings); } 

et comme ceci pour l’entrée:

 [HttpPost] public IActionResult Post([FromBodyCustomSerializationSettings]MyPostDto postDto) { ... } class FromBodyCustomSerializationSettingsAtsortingbute : ModelBinderAtsortingbute { public FromBodyCustomSerializationSettingsAtsortingbute() : base(typeof(MyModelBinder)) { BindingSource = BindingSource.Body; } } class MyModelBinder : IModelBinder { private readonly BodyModelBinder _bodyModelBinder; public MyModelBinder(IHttpRequestStreamReaderFactory readerFactory, ILoggerFactory loggerFactory, IOptions options, IOptions jsonOptions, ArrayPool charPool, ObjectPoolProvider objectPoolProvider) { var formatters = options.Value.InputFormatters.ToList(); int jsonFormatterIndex = formatters.FirstIndexOf(formatter => formatter is JsonInputFormatter); JsonSerializerSettings myCustomSettings = ... formatters[jsonFormatterIndex] = new JsonInputFormatter(loggerFactory.CreateLogger("MyCustomJsonFormatter"), myCustomSettings, charPool, objectPoolProvider, options.Value, jsonOptions.Value); _bodyModelBinder = new BodyModelBinder(formatters, readerFactory, loggerFactory, options.Value); } public Task BindModelAsync(ModelBindingContext bindingContext) { return _bodyModelBinder.BindModelAsync(bindingContext); } } 

En fait, j’ai trouvé un moyen. J’ai créé un atsortingbut qui implémente également IResultFilter et voici la méthode OnResultExecuting, où la magie opère:

 public void OnResultExecuting(ResultExecutingContext context) { var objectResult = context.Result as ObjectResult; if (objectResult != null) { var serializerSettings = new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }; var jsonFormatter = new JsonOutputFormatter( serializerSettings, ArrayPool.Shared); objectResult.Formatters.Add(jsonFormatter); } } 

Fondamentalement, je suis en train d’injecter un formateur JSON personnalisé dans chaque résultat d’object, avant que celui-ci ne soit envoyé au client. Il semble (mais je n’ai trouvé aucune documentation à ce sujet) qu’ASP.NET Core MVC préfère le formateur injecté à celui défini globalement.

J’espère que cela aide d’autres parce que je me débattais à ce sujet …