web-dev-qa-db-fra.com

Comment personnaliser les erreurs de liaison du modèle ASP.Net Core?

Je voudrais renvoyer uniquement des réponses d'erreur standardisées de mon API Web (Asp.net Core 2.1), mais je n'arrive pas à comprendre comment gérer les erreurs de liaison de modèle.

Le projet vient d'être créé à partir du modèle "Application Web ASP.NET Core"> "API". J'ai une action simple définie comme:

[Route("[controller]")]
[ApiController]
public class MyTestController : ControllerBase
{
    [HttpGet("{id}")]
    public ActionResult<TestModel> Get(Guid id)
    {
        return new TestModel() { Greeting = "Hello World!" };
    }
}

public class TestModel
{
    public string Greeting { get; set; }
}

Si je fais une demande pour cette action avec un Guid invalide (par exemple, https://localhost:44303/MyTest/asdf), Je récupère la réponse suivante:

{
    "id": [
        "The value 'asdf' is not valid."
    ]
}

J'ai le code suivant dans Startup.Configure:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    JsonErrorMiddleware.CreateSingleton(env);

    if (!env.IsDevelopment())
    {
        app.UseHsts();
    }

    app
        .UseHttpsRedirection()
        .UseStatusCodePages(async ctx => { await JsonErrorMiddleware.Instance.Invoke(ctx.HttpContext); })
        .UseExceptionHandler(new ExceptionHandlerOptions() { ExceptionHandler = JsonErrorMiddleware.Instance.Invoke })
        .UseMvc()
}

JsonErrorMiddleware est simplement une classe qui convertit les erreurs dans la forme correcte que je veux renvoyer et les met dans la réponse. Il n'est pas du tout appelé pour les erreurs de liaison de modèle (aucun Exception n'est levé et UseStatusCodePages n'est pas appelé).

Comment puis-je me connecter à la liaison de modèle pour fournir une réponse d'erreur standardisée à toutes les actions de mon projet?

J'ai lu un tas d'articles, mais ils semblent tous discuter de la gestion des exceptions globales ou des erreurs de validation.

13
Brian

Il convient de mentionner que ASP.NET Core 2.1 a ajouté l'attribut [ApiController], Qui, entre autres, gère automatiquement les erreurs de validation du modèle en renvoyant un BadRequestObjectResult avec ModelState transmis. Dans d'autres En d'autres termes, si vous décorez vos contrôleurs avec cet attribut, vous n'avez plus besoin de faire la vérification if (!ModelState.IsValid).

De plus, la fonctionnalité est également extensible. Dans Startup, vous pouvez ajouter:

services.Configure<ApiBehaviorOptions>(o =>
{
    o.InvalidModelStateResponseFactory = actionContext =>
        new BadRequestObjectResult(actionContext.ModelState);
});

Ce qui précède est exactement ce qui se passe déjà par défaut, mais vous pouvez personnaliser le lambda dans lequel InvalidModelStateResponseFactory est défini pour retourner ce que vous voulez.

29
Chris Pratt