web-dev-qa-db-fra.com

tâche async <IActionResult> vs tâche <T>

J'ai un contrôleur avec une action. Dans cette méthode d'action, j'ai une méthode async que j'appelle et c'est tout. C'est le code que j'utilise:

[HttpGet]
public Task<MyObject> Get()
{
    return _task.GetMyObject()
}

Cela sérial correctement dans le JSON que j'attends de lui. Maintenant, mon responsable insiste pour que la signature soit modifiée comme suit:

[HttpGet]
public async Task<IActionResult> Get()
{
    var data = await_task.GetMyObject();
    return Ok(data);
}

Je suis convaincu qu'il n'y a aucune raison pour que le code à await dans le contrôleur et puisse simplement renvoyer la Task, car rien ne dépend par la suite du résultat. Mis à part la génération de code supplémentaire (création d'une machine à états, etc.) réalisée pour la variable await, cette approche a-t-elle des implications d'un point de vue WebApi? Pour clarifier, je veux savoir si retourner une IActionResult est préférable à simplement renvoyer Task<MyObject> même s'il semble que les résultats soient les mêmes.

4
JohanP

Tâche <T>

Pro

Les tests unitaires ne nécessitent aucune coulée,

 Product product = await controller.Get();

Le gros avantage est que vos tests unitaires deviennent vraiment indépendants de la pile HTTP sous-jacente.

Swagger n'a besoin d'aucun attribut supplémentaire pour générer le schéma de réponse car swagger peut facilement détecter le type de résultat.

Un autre gros avantage est que vous pouvez réutiliser votre contrôleur dans un autre contrôleur lorsque la logique reste la même. 

De même, éviter await avant le renvoi donne une légère amélioration des performances car cette partie du code n'a pas besoin de la machine à états de tâches. Je pense que la future version C # omettra l’attente pour l’optimisation du compilateur.

Con

Le renvoi du code d'état d'erreur nécessite une exception.

    throw new HttpStatusException(404, "File not found");
    throw new HttpStatusException(409, "Unauthorized");

Tâche <IAsyncResult>

Pro

Vous pouvez renvoyer un code d’état HTTP tel que 

 return NotFound(); // (Status Code = 404)
 return Unauthorized(); // (Status Code = 409)

Con

Les tests unitaires nécessitent une coulée supplémentaire.

 Product productResult = ((await controller.Get()) as OkResult).Result as Product;

En raison d'un tel transfert, il devient difficile de réutiliser vos contrôleurs dans un autre contrôleur, ce qui entraîne une duplication de la logique.

Le générateur Swagger nécessite un attribut supplémentaire pour générer le schéma de réponse

 [ProducesResponseType(typeof(Product), 200)]

Cette approche est recommandée uniquement lorsque vous utilisez une logique ne faisant pas partie des tests unitaires, ni de votre logique métier telle que l'intégration OAuth avec des services tiers lorsque vous souhaitez vous concentrer davantage sur les résultats basés sur IActionResult tels que Challenge, Redirect etc. .

3
Akash Kava

Les actions peuvent renvoyer n'importe quoi, mais renvoient fréquemment une instance de IActionResult (ou Task<IActionResult> pour les méthodes asynchrones) qui produit une réponse. La méthode d'action est responsable du choix de quel type de réponse. Le résultat de l'action fait la réponse.

Si une action renvoie une implémentation IActionResult et que le contrôleur hérite de Controller, les développeurs disposent de nombreuses méthodes d'assistance correspondant à de nombreux choix. Les résultats des actions renvoyant des objets qui ne sont pas des types IActionResult seront sérialisés à l'aide de l'implémentation IOutputFormatter appropriée.

Pour les actions non triviales avec plusieurs types ou options de retour (par exemple, différents codes d'état HTTP basés sur le résultat des opérations effectuées), préférez IActionResult comme type de retour.

1
Feiyu Zhou

ASP.NET MVC est une convention sur la configuration framework. Cela signifie que tout futur responsable de votre code, y compris votre futur utilisateur, s'attendra à ce que le code soit écrit d'une certaine manière afin de réduire le nombre de fichiers de classe à inspecter pour apporter des modifications ou des ajouts.

Bien que le résultat puisse être le même de vos deux options techniquement différentes, l'approche classique consiste à asynchroniser/attendre vos résultats. Toute autre chose que cette convention pourrait potentiellement semer la confusion chez les futurs responsables. De plus, les versions futures de MVC risquent de casser votre code de manière inconnue, car vous ne respectiez pas la convention.

Un bon leadership des équipes de développement de logiciels inclut notamment la volonté de réduire les besoins globaux en personnel de l’organisation en simplifiant la maintenance future éventuelle du code. Votre responsable essaie peut-être de promouvoir ce concept.

1
Jim Yarbro

L'équipe centrale ASP.NET, tout en unifiant MVC et l'API Web (contrôleur et ApiController), a résumé IActionResult pour un mécanisme de gestion des exceptions robuste. 

Le lancement d'exceptions pour le contrôle de flux constitue un anti-modèle pour les méthodes d'action.

[HttpGet]
public async Task<MyObject> Get()
{
    var data = await _task.GetMyObject()
    if(data == null)
    {
        return NotFound(); //Or, return Request.CreateResponse(HttpStatusCode.NotFound)
        // Versus, throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }

    return Ok(data);
}

Remarque: NotFound(), Ok() etc. sont des éléments IHttpActionResult de l’époque WEBAPI2 qui ne sont pas nouveaux dans le noyau asp.net.

0
Bishnu Rawal