Unterschied zwischen ApiController und Controller in ASP.NET MVC

343

Ich habe mit ASP.NET MVC 4 Beta herumgespielt und sehe jetzt zwei Arten von Controllern: ApiControllerund Controller.

Ich bin wenig verwirrt darüber, in welchen Situationen ich einen bestimmten Controller auswählen kann.

Zum Beispiel: Wenn ich eine Ansicht zurückgeben möchte, muss ich sie verwenden ApiControlleroder das Gewöhnliche Controller? Mir ist bekannt, dass die WCF-Web-API jetzt in MVC integriert ist.

Da wir jetzt beide Controller verwenden können, kann jemand bitte angeben, in welchen Situationen er sich für den entsprechenden Controller entscheiden soll.

VJAI
quelle
23
Wichtig: ASPNET Core ‚verschmolzen‘ hat ApiControllerund Controllerso , wenn Sie mit dem neueren .NET Sie ApiController Sorgen nicht mehr brauchen - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver
2
Ich bin froh, dass sie es getan haben! Ich habe dies vor langer Zeit übrigens vorausgesagt. Prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Antworten:

356

Verwenden Sie Controller, um Ihre normalen Ansichten zu rendern. Die ApiController-Aktion gibt nur Daten zurück, die serialisiert und an den Client gesendet wurden.

hier ist der Link

Zitat:

Hinweis Wenn Sie mit ASP.NET MVC gearbeitet haben, sind Sie bereits mit Controllern vertraut. Sie funktionieren in der Web-API ähnlich, aber Controller in der Web-API leiten sich von der ApiController-Klasse anstelle der Controller-Klasse ab. Der erste große Unterschied, den Sie feststellen werden, besteht darin, dass Aktionen auf Web-API-Controllern keine Ansichten zurückgeben, sondern Daten zurückgeben.

ApiController sind auf die Rückgabe von Daten spezialisiert. Sie sorgen beispielsweise dafür, dass die Daten transparent in das vom Client angeforderte Format serialisiert werden. Außerdem folgen sie standardmäßig einem anderen Routing-Schema (wie in: Zuordnen von URLs zu Aktionen) und stellen gemäß Konvention eine REST-vollständige API bereit.

Sie könnten wahrscheinlich alles mit einem Controller anstelle eines ApiControllers mit etwas (?) Manueller Codierung tun. Am Ende bauen beide Controller auf der ASP.NET-Grundlage auf. Eine REST-vollständige API ist heutzutage jedoch eine so häufige Anforderung, dass WebAPI erstellt wurde, um die Implementierung einer solchen API zu vereinfachen.

Es ist ziemlich einfach, sich zwischen beiden zu entscheiden: Wenn Sie eine HTML-basierte Web- / Internet- / Intranet-Anwendung schreiben - möglicherweise mit dem gelegentlichen AJAX-Aufruf, der hier und da json zurückgibt - bleiben Sie bei MVC / Controller. Wenn Sie einem System eine datengesteuerte / REST-fähige Schnittstelle bereitstellen möchten, verwenden Sie WebAPI. Sie können natürlich beide kombinieren, wenn ein ApiController AJAX-Anrufe von einer MVC-Seite aus abwickelt.

Um ein Beispiel aus der Praxis zu geben: Ich arbeite derzeit mit einem ERP-System, das seinen Entitäten eine REST-vollständige API bietet. Für diese API wäre WebAPI ein guter Kandidat. Gleichzeitig bietet das ERP-System eine stark AJAX-fähige Webanwendung, mit der Sie Abfragen für die REST-vollständige API erstellen können. Die Webanwendung selbst könnte als MVC-Anwendung implementiert werden, wobei die WebAPI zum Abrufen von Metadaten usw. verwendet wird.

Andre Loker
quelle
9
Hinweis: Wie werden Ihre Daten formatiert, da sie über das Kabel gesendet werden? Die Art und Weise, wie Daten, die ein ApiController zurückgibt, formatiert werden, wird durch Inhaltsverhandlung und GlobalConfiguration.Configuration.Formatters ... Link: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith bestimmt
1
Ist es richtig zu sagen, dass die Web-API eine gemeinsame Plattform für Websites, Mobilgeräte usw. ist? und wir könnten Klassenbibliothek anstelle von Web-API verwenden?
Imad Alazani
Vielen Dank an @ TimLovell-Smith für Ihren Hinweis, denn für mich beantwortet Andre die Frage nicht: Da ein Controller auch Daten zurückgeben kann, erklärt er nicht, warum ApiController existiert und nützlich ist.
JYL
2
@JYL Ich habe meine Antwort erweitert, um detailliertere Informationen bereitzustellen.
Andre Loker
2
Ich habe es nicht wirklich verstanden, als Sie sagten "Bereitstellung einer REST-vollständigen API gemäß Konvention" . Wie bietet es eine REST-vollständige API? Kommt es nicht darauf an, welche Daten Sie von der API zurückgeben? Der Controller enthält nichts, was die API zwingt (oder sogar erleichtert), REST-voll zu sein.
Nawaz
192

Welches möchten Sie lieber schreiben und pflegen?

ASP.NET MVC

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

ASP.NET-Web-API

public class TweetsController : ApiController {
  // GET: /Api/Tweets/
  public List<Tweet> Get() {
    return Twitter.GetTweets();
  }
}
Manish Jain
quelle
6
Es ist ein guter Punkt, aber ApiController ist mehr als nur JSON-Serialisierung. Es kümmert sich auch darum, die Anforderung zu überprüfen und XML zurückzugeben, wenn dies der Akzeptiertyp ist.
Jake Almer
10
Wenn Sie den asp.net-Kern verwenden, werden alle von der ControllerKlasse abgeleitet .
Tân
2
Dies scheint ein altes Beispiel zu sein. Jetzt müssen wir uns nicht mehr ApiControllernur um die : ControllerArbeit kümmern. Können Sie auch ein neues Dot Net Core Controller-Beispiel hinzufügen
Ashish Kamble,
@AshishKamble, Anstelle von ApiController wird jetzt ControllerBase verwendet.
Vladimir Shiyanov
Ehrlich gesagt hätte ich lieber die Json()Version. Es ist klarer und expliziter. Ich mag es nicht, wenn eine Menge schwarzer Magie versucht, herauszufinden, wie mein Code auf eine Anfrage reagieren wird.
Jez
27

Ich liebe die Tatsache, dass MVC6 von ASP.NET Core die beiden Muster zu einem zusammengeführt hat, da ich oft beide Welten unterstützen muss. Es ist zwar richtig, dass Sie jede Standard-MVC optimieren Controller(und / oder Ihre eigenen ActionResultKlassen entwickeln) können, um sich wie eine zu verhalten ApiController, aber es kann sehr schwierig sein, sie zu warten und zu testen: Darüber hinaus müssen die zurückgegebenen Controller- Methoden ActionResultmit anderen gemischt werden Die Rückgabe von Rohdaten / serialisierten IHttpActionResultDaten / Daten kann aus Entwicklersicht sehr verwirrend sein, insbesondere wenn Sie nicht alleine arbeiten und andere Entwickler mit diesem hybriden Ansatz auf den neuesten Stand bringen müssen.

Die beste Technik, die ich bisher entwickelt habe, um dieses Problem in ASP.NET-Nicht-Core-Webanwendungen zu minimieren, besteht darin, das Web-API-Paket in die MVC-basierte Webanwendung zu importieren (und ordnungsgemäß zu konfigurieren), damit ich das Beste aus beiden herausholen kann Welten: Controllersfür Ansichten, ApiControllersfür Daten.

Dazu müssen Sie Folgendes tun:

  • Installieren Sie die folgenden Web-API-Pakete mit NuGet: Microsoft.AspNet.WebApi.Coreund Microsoft.AspNet.WebApi.WebHost.
  • Fügen Sie Ihrem /Controllers/Ordner einen oder mehrere ApiController hinzu.
  • Fügen Sie Ihrem /App_Config/Ordner die folgende Datei WebApiConfig.cs hinzu:

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 }
        );
    }
}

Schließlich müssen Sie die oben genannte Klasse in Ihrer Startup- Klasse registrieren (entweder Startup.csoder Global.asax.cs, je nachdem, ob Sie die OWIN-Startup-Vorlage verwenden oder nicht).

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);
    // ...
}

Dieser Ansatz - zusammen mit seinen Vor- und Nachteilen - wird in diesem Beitrag, den ich in meinem Blog geschrieben habe, näher erläutert .

Darkseal
quelle
1
gute Sache. Diese Funktionalität ist jedoch bereits in vs2015 integriert. Wenn Sie ein webapi asp.net-Projekt erstellen, erledigt es automatisch den gesamten Kesselplattencode für Sie.
Suomi-Dev
@Darkseal Könnten Sie bitte etwas näher auf "Es kann sehr schwer zu warten und zu testen sein" näher eingehen? (Ich habe Ihren Blog-Beitrag gelesen.) Ich habe WebAPI2 verwendet und es gefällt mir, wie es funktioniert. Ich kann jedoch nicht den "wirklich großen Vorteil" herausfinden, außer dass es "die übliche Art ist, Dinge zu tun". Es ist einfach genug, wenn klassische MVC-Controller "manuell" serialisierte Zeichenfolgen zurückgeben. Das Hinzufügen eines json / xml-Schalters mit dem Verb http Accept dauert nicht viel. All das könnte in eine nette Utility-Methode verpackt werden. Danke.
ValGe
2
@ValGe, siehe @ manish-jain Antwort oben. ControllerKurz gesagt, eine Rückgabe einer Json-serialisierten Zeichenfolge, die in eine Zeichenfolge eingeschlossen ActionResultist, ist definitiv schwieriger zu testen und zu verwalten als eine, ApiControllerdie so eingestellt werden kann, dass eine Liste von [Serializable]Elementen direkt zurückgegeben wird . Jede Testmethode wäre viel einfacher zu schreiben, da Sie nicht jedes Mal manuell de-serialisieren müssen: Dies gilt auch für nahezu jede Systemintegrationsaufgabe mit ASP.NET oder anderen Frameworks. Controllerssind großartig, aber ApiControllersbesser für RESTful-Aufgaben geeignet, zumindest in .NET Framework 4.x
Darkseal
1

Jede Methode in der Web-API gibt Daten (JSON) ohne Serialisierung zurück.

Um jedoch JSON-Daten in MVC-Controllern zurückzugeben, setzen wir den zurückgegebenen Aktionsergebnistyp auf JsonResult und rufen die Json-Methode für unser Objekt auf, um sicherzustellen, dass es in JSON gepackt ist.

Shailesh Uke
quelle
1

Der Hauptunterschied besteht darin, dass die Web-API ein Dienst für jeden Client und alle Geräte ist und MVC Controller nur seinen Client bedient. Das gleiche, weil es MVC-Plattform ist.

ANJYR - KODEXPRESSION
quelle
-1

Es ist ziemlich einfach, sich zwischen beiden zu entscheiden: Wenn Sie eine HTML-basierte Web- / Internet- / Intranet-Anwendung schreiben - möglicherweise mit dem gelegentlichen AJAX-Aufruf, der hier und da json zurückgibt - bleiben Sie bei MVC / Controller. Wenn Sie eine datengesteuerte / REST-fähige Schnittstelle für ein System bereitstellen möchten, verwenden Sie WebAPI. Sie können natürlich beide kombinieren, wenn ein ApiController AJAX-Anrufe von einer MVC-Seite aus abwickelt. Grundsätzlich wird Controller für MVC und API-Controller für Rest-API verwendet. Sie können beide in demselben Programm verwenden, wie Sie es benötigen


quelle