Le type Enum ne fonctionne plus dans l'objet de demande FromBody .Net core 3.0

15

J'ai récemment mis à niveau mon API Web de .Net core 2.2 vers .Net core 3.0 et j'ai remarqué que mes demandes recevaient maintenant une erreur lorsque je passais une énumération dans un message à mon point de terminaison. Par exemple:

J'ai le modèle suivant pour mon point de terminaison api:

    public class SendFeedbackRequest
    {
        public FeedbackType Type { get; set; }
        public string Message { get; set; }
    }

À quoi ressemble le FeedbackType:

    public enum FeedbackType
    {
        Comment,
        Question
    }

Et voici la méthode du contrôleur:

    [HttpPost]
    public async Task<IActionResult> SendFeedbackAsync([FromBody]SendFeedbackRequest request)
    {
        var response = await _feedbackService.SendFeedbackAsync(request);

        return Ok(response);
    }

Où j'envoie ceci en tant que corps de message au contrôleur:

{
    message: "Test"
    type: "comment"
}

Et je reçois maintenant l'erreur suivante sur ce point de terminaison:

The JSON value could not be converted to MyApp.Feedback.Enums.FeedbackType. Path: $.type | LineNumber: 0 | BytePositionInLine: 13."

Cela fonctionnait dans 2.2 et a commencé l'erreur dans 3.0. J'ai vu parler du changement de sérialiseur json en 3.0, mais je ne sais pas comment cela devrait être géré.

Shawn
la source

Réponses:

18

Le framework n'utilise plus Json.Net par défaut et le nouveau sérialiseur intégré a ses propres problèmes et sa propre courbe d'apprentissage pour obtenir les fonctionnalités attendues.

Si vous souhaitez revenir à la valeur par défaut précédente de l'utilisation Newtonsoft.Json, vous devrez effectuer les opérations suivantes:

  1. Installez le package NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson .

  2. En ConfigureServices()ajoutant un appel àAddNewtonsoftJson()

public void ConfigureServices(IServiceCollection services) {
    //...

    services.AddControllers()
        .AddNewtonsoftJson(); //<--

    //...
}
Nkosi
la source
3
Je voudrais souligner que les deux étapes doivent être franchies. Ce qui est assez évident, mais si vous oubliez le package Nuget et que vous ajoutez uniquement "AddNewtonsoftJson ()", votre code se compile et s'exécute très bien, alors que cela ne fonctionne pas.
Jean-Paul Smit
18

Pour ceux qui recherchent un extrait

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    });
}
Pashec
la source
Ça devrait l'être StringEnumConverter, non JsonStringEnumConverter.
villecoder Il y a
6

La prise en charge de la sérialisation des énumérations sous forme de chaînes existe déjà si vous utilisez le JsonStringEnumConverter intégré et le transmettez aux JsonSerializerOptions: https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonstringenumconverter ? view = netcore-3.0

Voici un exemple de test qui l'utilise: https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/tests/Serialization/ReadScenarioTests.cs#L17

Yigit Tanriverdi
la source
1
Pour ceux qui ne savent pas comment passer JsonStringEnumConverter dans JsonSerialzerOptions, voici le code:services.AddMvc() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.JsonSerializerOptions.IgnoreNullValues = true; });
Anthony Huang