Différence entre ApiController et Controller dans ASP.NET MVC

343

J'ai joué avec ASP.NET MVC 4 beta et je vois maintenant deux types de contrôleurs: ApiControlleret Controller.

Je suis peu confus dans quelles situations je peux choisir un contrôleur particulier.

Par exemple: si je veux retourner une vue alors je dois utiliser ApiControllerou l'ordinaire Controller? Je suis conscient que l'API Web WCF est désormais intégrée à MVC.

Depuis maintenant, nous pouvons utiliser les deux contrôleurs. Quelqu'un peut-il indiquer les situations à adopter pour le contrôleur correspondant.

VJAI
la source
23
Important: ASPNET Core a «fusionné» ApiControlleret Controllerdonc si vous utilisez le nouveau .NET, vous n'avez plus à vous soucier d'ApiController - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver
2
Heureux qu'ils l'aient fait! Je l'avais prédit depuis longtemps par la façon dont prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Réponses:

356

Utilisez Controller pour rendre vos vues normales. L'action ApiController renvoie uniquement les données sérialisées et envoyées au client.

Voici le lien

Citation:

Remarque Si vous avez travaillé avec ASP.NET MVC, vous connaissez déjà les contrôleurs. Ils fonctionnent de manière similaire dans l'API Web, mais les contrôleurs dans l'API Web dérivent de la classe ApiController au lieu de la classe Controller. La première différence majeure que vous remarquerez est que les actions sur les contrôleurs d'API Web ne renvoient pas de vues, elles renvoient des données.

Les ApiControllers sont spécialisés dans le retour de données. Par exemple, ils prennent en charge la sérialisation transparente des données dans le format demandé par le client. En outre, ils suivent un schéma de routage différent par défaut (comme dans: mappage des URL aux actions), fournissant une API REST par convention.

Vous pourriez probablement faire n'importe quoi en utilisant un contrôleur au lieu d'un ApiController avec le codage manuel (?). En fin de compte, les deux contrôleurs s'appuient sur la fondation ASP.NET. Mais avoir une API REST-ful est une exigence tellement courante aujourd'hui que WebAPI a été créé pour simplifier la mise en œuvre d'une telle API.

Il est assez simple de décider entre les deux: si vous écrivez une application Web / Internet / Intranet basée sur HTML - peut-être avec l'appel AJAX occasionnel renvoyant json ici et là - restez avec MVC / Controller. Si vous souhaitez fournir une interface pilotée par les données / REST à un système, optez pour WebAPI. Bien sûr, vous pouvez combiner les deux en ayant un ApiController pour répondre aux appels AJAX à partir d'une page MVC.

Pour donner un exemple concret: je travaille actuellement avec un système ERP qui fournit une API REST-ful à ses entités. Pour cette API, WebAPI serait un bon candidat. Dans le même temps, le système ERP fournit une application Web hautement AJAX que vous pouvez utiliser pour créer des requêtes pour l'API REST-ful. L'application Web elle-même pourrait être implémentée en tant qu'application MVC, en utilisant WebAPI pour récupérer des métadonnées, etc.

Andre Loker
la source
9
Remarque: étant donné que vos données seront envoyées via le câble, comment seront-elles formatées? La façon dont les données qu'un ApiController renvoie est formatée est déterminée par la négociation de contenu et le lien GlobalConfiguration.Configuration.Formatters ...: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith
1
Est-il exact de dire que l'API Web est une plate-forme commune pour site Web, mobile, etc.? et nous pourrions utiliser la bibliothèque de classes au lieu de l'API Web?
Imad Alazani
Merci @ TimLovell-Smith pour votre note, car pour moi Andre ne répond pas à la question: comme un contrôleur peut également retourner des données, cela n'explique pas pourquoi ApiController existe et est utile.
JYL
2
@JYL J'ai augmenté ma réponse pour fournir des informations plus détaillées.
Andre Loker
2
Je n'ai pas vraiment compris quand vous avez dit "fournir une API REST par convention" . Comment fournit-il l'API REST-ful? Cela ne dépend-il pas des données que vous renvoyez de l'API? Il n'y a rien dans le contrôleur qui force (ou même facilite) l'API à être REST-ful.
Nawaz
192

Que préférez-vous écrire et conserver?

ASP.NET MVC

public class TweetsController : Controller {
  // GET: /Tweets/
  [HttpGet]
  public ActionResult Index() {
    return Json(Twitter.GetTweets(), JsonRequestBehavior.AllowGet);
  }
}

API Web ASP.NET

public class TweetsController : ApiController {
  // GET: /Api/Tweets/
  public List<Tweet> Get() {
    return Twitter.GetTweets();
  }
}
Manish Jain
la source
6
C'est un bon point, mais ApiController est plus qu'une simple sérialisation JSON. Il prend également en charge la consultation de la demande et le renvoi de XML s'il s'agit du type accepté.
Jake Almer
10
Si vous utilisez le noyau asp.net, ils sont tous dérivés de la Controllerclasse.
Tân
2
Cela semble vieux exemples, Maintenant , nous ne avez pas besoin de vous soucier ApiControllerseulement des : Controllerœuvres, pouvez - vous ajouter de nouveaux points de base par exemple contrôleur réseau trop
Ashish Kamble
@AshishKamble, Au lieu d'ApiController, ControllerBase est maintenant utilisé.
Vladimir Shiyanov
Honnêtement, je préfère avoir la Json()version. C'est plus clair et plus explicite. Je n'aime pas beaucoup de magie noire en essayant de comprendre comment mon code va répondre à une demande.
Jez
27

J'adore le fait que le MVC6 d'ASP.NET Core a fusionné les deux modèles en un, car j'ai souvent besoin de prendre en charge les deux mondes. Bien qu'il soit vrai que vous pouvez modifier n'importe quel MVC standard Controller(et / ou développer vos propres ActionResultclasses) pour agir et se comporter comme un an ApiController, il peut être très difficile à maintenir et à tester: en plus de cela, avoir des méthodes de Contrôleurs retournant ActionResultmélangées avec d'autres le retour de données brutes / sérialisées / IHttpActionResultpeut être très déroutant du point de vue du développeur, en particulier si vous ne travaillez pas seul et que vous avez besoin d'accélérer d'autres développeurs avec cette approche hybride.

La meilleure technique que j'ai trouvée jusqu'à présent pour minimiser ce problème dans les applications Web non Core ASP.NET consiste à importer (et à configurer correctement) le package d'API Web dans l'application Web basée sur MVC, afin que je puisse avoir le meilleur des deux. mondes: Controllerspour les vues, ApiControllerspour les données.

Pour ce faire, vous devez procéder comme suit:

  • Installez les packages d'API Web suivants à l'aide de NuGet: Microsoft.AspNet.WebApi.Coreet Microsoft.AspNet.WebApi.WebHost.
  • Ajoutez un ou plusieurs ApiControllers à votre /Controllers/dossier.
  • Ajoutez le fichier WebApiConfig.cs suivant à votre /App_Config/dossier:

using System.Web.Http;

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Enfin, vous devrez enregistrer la classe ci-dessus dans votre classe de démarrage (soit Startup.csou Global.asax.cs, selon que vous utilisez le modèle de démarrage OWIN ou non).

Startup.cs

 public void Configuration(IAppBuilder app)
 {
    // Register Web API routing support before anything else
    GlobalConfiguration.Configure(WebApiConfig.Register);

    // The rest of your file goes there
    // ...
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    ConfigureAuth(app);
    // ...
}

Global.asax.cs

protected void Application_Start()
{
    // Register Web API routing support before anything else
    GlobalConfiguration.Configure(WebApiConfig.Register);

    // The rest of your file goes there
    // ...
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    // ...
}

Cette approche - avec ses avantages et ses inconvénients - est expliquée plus en détail dans cet article que j'ai écrit sur mon blog.

Darkseal
la source
1
bonne chose. mais cette fonctionnalité est déjà intégrée à vs2015. si vous créez un projet webapi asp.net, il fera automatiquement tout le code de la plaque de la chaudière pour vous.
suomi-dev
@Darkseal pourriez-vous s'il vous plaît développer un peu "cela peut être très difficile à maintenir et à tester"? (J'ai lu votre article de blog) J'ai utilisé WebAPI2 et j'aime son fonctionnement. Cependant, je ne peux pas comprendre le "vrai grand avantage" en plus d'avoir "la façon courante de faire les choses". Il est assez facile d'avoir des contrôleurs MVC classiques renvoyant des chaînes sérialisées "manuellement". L'ajout d'un commutateur json / xml avec le verbe http Accept ne prend pas beaucoup. Tout cela pourrait être enveloppé dans une belle méthode utilitaire. Merci.
ValGe
2
@ValGe, voir la réponse @ manish-jain ci-dessus. En résumé, un Controllerretour d'une chaîne sérialisée Json enveloppée dans un ActionResultest définitivement plus difficile à tester et à maintenir qu'un ApiControllerqui peut être configuré pour renvoyer directement une liste d' [Serializable]éléments. Toute méthode de test serait beaucoup plus facile à écrire, car vous n'aurez pas à désérialiser manuellement à chaque fois: la même chose peut être dite pour presque toutes les tâches d'intégration de système avec ASP.NET ou d'autres cadres. Controllerssont excellents, mais ApiControllersconviennent mieux aux tâches RESTful, au moins dans .NET Framework 4.x
Darkseal
1

Chaque méthode de l'API Web renvoie des données (JSON) sans sérialisation.

Cependant, afin de renvoyer les données JSON dans les contrôleurs MVC, nous allons définir le type de résultat d'action renvoyé sur JsonResult et appeler la méthode Json sur notre objet pour nous assurer qu'il est conditionné dans JSON.

Shailesh Uke
la source
1

La principale différence est la suivante: l'API Web est un service pour tout client, tout appareil et MVC Controller ne sert que son client. De même car il s'agit de la plateforme MVC.

ANJYR - KODEXPRESSION
la source
-1

Il est assez simple de décider entre les deux: si vous écrivez une application Web / Internet / Intranet basée sur HTML - peut-être avec l'appel AJAX occasionnel renvoyant json ici et là - restez avec MVC / Controller. Si vous souhaitez fournir une interface pilotée par les données / REST à un système, optez pour WebAPI. Bien sûr, vous pouvez combiner les deux en ayant un ApiController pour répondre aux appels AJAX à partir d'une page MVC. Fondamentalement, le contrôleur est utilisé pour mvc et api-controller est utilisé pour Rest-API, vous pouvez utiliser les deux dans le même programme que votre besoin


la source