2 votes

C# REST API - comment étendre l'erreur d'état du modèle avec un code d'erreur

Je suis en train de créer une API Web ASP.net Core (.net 5) pour servir des données à une application à page unique (SPA). J'utilise DataAnnotations ( System.ComponentModel.DataAnnotations ) pour effectuer la validation de l'état du modèle d'une manière très standard dans mon contrôleur. Je veux m'assurer que mes réponses d'erreur reviennent d'une manière très cohérente (et qu'elles soient traduisibles dans le front-end !).

Contrôleur MVC

L'exemple de contrôleur est le suivant :

[ApiController, Route("[controller]")]
public class AgencyController : Controller
{
    private readonly IOptions<ApiBehaviorOptions> _apiBehaviorOptions;

    public AgencyController(IOptions<ApiBehaviorOptions> apiBehaviorOptions)
    {
        _apiBehaviorOptions = apiBehaviorOptions;
    }

    [HttpPost]
    [ProducesResponseType(typeof(void), (int) HttpStatusCode.OK)]
    [ProducesResponseType(typeof(ProblemDetails), (int) HttpStatusCode.BadRequest)]
    public IActionResult Create([FromBody] ExampleCreateModel createModel)
    {
        // If the email already exists, add the custom error.
        var emailExists = EmailAlreadyExists(createModel.Email);
        if (emailExists)
        {
            ModelState.AddModelError("Email", "Email already exists");
            return _apiBehaviorOptions.Value.InvalidModelStateResponseFactory(ControllerContext);
        }

        // Return some relevant status...
        return Ok();
    }

    // Real verification implementation would go here....
    private bool EmailAlreadyExists(string email) => true;
}

L'exemple de code ci-dessus montre un contrôleur qui prend le modèle POCO (illustré ci-dessous) et, s'il passe la validation d'attribut, effectue une validation en ligne supplémentaire pour s'assurer que l'adresse électronique n'existe pas déjà (pseudo-code pour la vérification de l'existence de l'adresse électronique).

Modèle d'échantillon

public class ExampleCreateModel
{
    [Required] 
    public string Name { get; set; } = "";

    [Required]
    [EmailAddress(ErrorMessage = "Invalid email format")]
    public string Email { get; set; } = "";
}

Format de la réponse d'erreur

L'échec de la validation du modèle présenté ci-dessus produit l'objet d'erreur standard de l'application MVC dans ce format (exemple) :

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-6b30709ed71b7347afd41e0ed58e1ccb-e3ede2ff7591a24d-00",
  "errors": {
    "Email": [
      "Email already exists"
    ]
  }
}

ce format est cohérent à la fois pour la validation régulière des attributs et pour la validation personnalisée en ligne dans le code ci-dessus

Ma question

L'avantage d'utiliser les erreurs intégrées est la cohérence (et le respect d'un modèle standard). MAIS l'un des inconvénients pour moi est que j'aimerais renvoyer des codes d'erreur ainsi que du texte dans le cadre de l'objet d'erreur, afin que l'interface utilisateur puisse les traduire, mais cela ne semble pas facile à prendre en charge. Par exemple, une erreur "Email existe déjà" pourrait être une erreur 3001 et l'interface utilisateur pourrait afficher un 3001 dans différentes langues.

Existe-t-il un moyen standard d'utiliser les attributs DataAnnotation existants pour inclure des informations supplémentaires ? Ainsi, le modèle POCO deviendrait quelque chose comme ceci :

public class ExampleCreateModel
{
    [Required(ErrorCode = 3000)] 
    public string Name { get; set; } = "";

    [Required]
    [EmailAddress(ErrorMessage = "Invalid email format", ErrorCode = 3001)]
    public string Email { get; set; } = "";
}

Il en résulte un objet d'erreur similaire à celui-ci :

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-6b30709ed71b7347afd41e0ed58e1ccb-e3ede2ff7591a24d-00",
  "errors": {
    "Email": [
      { "message": "Email already exists", "errorCode": 3002 }
    ]
  }
}

Pour plus de clarté, mon objectif est de donner à l'interface utilisateur la possibilité de traduire facilement le code d'erreur, tout en assurant la cohérence des erreurs à l'aide de la réponse d'erreur prête à l'emploi.

Merci d'avance pour tout conseil !

0voto

Ian Kemp Points 6408

Existe-t-il un moyen standard d'utiliser les attributs DataAnnotation existants pour inclure des informations supplémentaires ?

Non.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X