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 !