Differenza tra ApiController e Controller in ASP.NET MVC


343

Ho giocato con ASP.NET MVC 4 beta e ora vedo due tipi di controller: ApiControllere Controller.

Sono un po 'confuso in quali situazioni posso scegliere un determinato controller.

Ad esempio: se voglio restituire una vista, allora devo usare ApiControllero l'ordinario Controller? Sono consapevole che l'API Web WCF è ora integrata con MVC.

Da ora possiamo usare entrambi i controller qualcuno può indicare in quali situazioni andare per il controller corrispondente.


23
Importante: ASPNET Core si è "unito" ApiControllere Controllerquindi se stai utilizzando .NET più recente non devi più preoccuparti di ApiController - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver,

2
Sono contento di averlo fatto! Ho predetto così tanto tempo fa prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Risposte:


356

Utilizza Controller per eseguire il rendering delle visualizzazioni normali. L'azione ApiController restituisce solo i dati serializzati e inviati al client.

Ecco il link

Citazione:

Nota Se hai lavorato con ASP.NET MVC, hai già familiarità con i controller. Funzionano in modo simile nell'API Web, ma i controller nell'API Web derivano dalla classe ApiController anziché dalla classe Controller. La prima grande differenza che noterai è che le azioni sui controller API Web non restituiscono visualizzazioni, ma restituiscono dati.

Gli ApiController sono specializzati nella restituzione dei dati. Ad esempio, si occupano di serializzare in modo trasparente i dati nel formato richiesto dal client. Inoltre, seguono uno schema di routing diverso per impostazione predefinita (come in: mapping degli URL alle azioni), fornendo un'API REST-ful per convenzione.

Probabilmente potresti fare qualsiasi cosa usando un controller invece di un ApiController con la codifica manuale (?). Alla fine, entrambi i controller si basano sulla base ASP.NET. Ma avere un'API REST completa è un requisito così comune oggi che WebAPI è stato creato per semplificare l'implementazione di tale API.

È abbastanza semplice decidere tra i due: se stai scrivendo un'applicazione web / internet / intranet basata su HTML - forse con la chiamata AJAX occasionale che restituisce json qua e là - resta con MVC / Controller. Se si desidera fornire un'interfaccia basata sui dati / REST a un sistema, utilizzare WebAPI. È possibile combinare entrambi, ovviamente, con un ApiController per soddisfare le chiamate AJAX da una pagina MVC.

Per fare un esempio reale: attualmente sto lavorando con un sistema ERP che fornisce un'API REST alle sue entità. Per questa API, WebAPI sarebbe un buon candidato. Allo stesso tempo, il sistema ERP fornisce un'applicazione Web altamente basata su AJAX che è possibile utilizzare per creare query per l'API REST-ful. L'applicazione Web stessa potrebbe essere implementata come un'applicazione MVC, utilizzando WebAPI per recuperare metadati ecc.


9
Nota: poiché i tuoi dati verranno inviati via cavo, come verranno formattati? Il modo in cui i dati restituiti da un ApiController viene formattato è determinato dalla negoziazione del contenuto e da GlobalConfiguration.Configuration.Formatters ... link: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith

1
È corretto affermare che l'API Web è una piattaforma comune per siti Web, dispositivi mobili, ecc.? e potremmo usare la libreria di classi anziché l'API Web?
Imad Alazani,

Grazie @ TimLovell-Smith per la tua nota, perché per me Andre non risponde alla domanda: poiché un controller può anche restituire dati, non spiega perché ApiController esiste ed è utile.
JYL,

2
@JYL Ho aumentato la mia risposta per fornire informazioni più dettagliate.
Andre Loker,

2
Non ho davvero capito quando hai detto "fornire un'API REST-ful per convenzione" . Come fornisce l'API REST-ful? Non dipende da quali dati restituisci dall'API? Non c'è nulla nel controller che forza (o addirittura facilita) l'API ad essere REST-ful.
Nawaz,

192

Quale preferiresti scrivere e mantenere?

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

6
È un buon punto, ma ApiController è molto più di una semplice serializzazione JSON. Si occupa anche di esaminare la richiesta e restituire XML se questo è il tipo di accettazione.
Jake Almer,

10
Se usi asp.net core, tutti sono derivati ​​dalla Controllerclasse.
Tân,

2
Sembrano vecchi esempi, ora non dobbiamo preoccuparci ApiControllersolo dei : Controllerlavori, puoi aggiungere anche un nuovo esempio di controller core net dot
Ashish Kamble,

@AshishKamble, Invece di ApiController, ControllerBase è ora utilizzato.
Vladimir Shiyanov,

Onestamente, preferirei avere la Json()versione. È più chiaro ed esplicito. Non mi piace un sacco di magia nera nel tentativo di capire come il mio codice risponderà a una richiesta.
Jez

27

Adoro il fatto che MVC6 di ASP.NET Core abbia unito i due pattern in uno solo perché spesso ho bisogno di supportare entrambi i mondi. Mentre è vero che puoi modificare qualsiasi MVC standard Controller(e / o sviluppare le tue ActionResultclassi) per agire e comportarsi come un semplice ApiController, può essere molto difficile da mantenere e testare: inoltre, i metodi di Controller tornano ActionResultmescolati con altri la restituzione di dati grezzi / serializzati / IHttpActionResultpuò essere molto confusa dal punto di vista dello sviluppatore, specialmente se non stai lavorando da solo e hai bisogno di portare altri sviluppatori ad accelerare con quell'approccio ibrido.

La migliore tecnica con cui sono arrivato finora per ridurre al minimo tale problema nelle applicazioni Web non core ASP.NET consiste nell'importare (e configurare correttamente) il pacchetto API Web nell'applicazione Web basata su MVC, quindi posso avere il meglio di entrambi mondi: Controllersper Views, ApiControllersper dati.

Per fare ciò, devi fare quanto segue:

  • Installa i seguenti pacchetti API Web usando NuGet: Microsoft.AspNet.WebApi.Coree Microsoft.AspNet.WebApi.WebHost.
  • Aggiungi uno o più ApiController alla tua /Controllers/cartella.
  • Aggiungi il seguente file WebApiConfig.cs alla tua /App_Config/cartella:

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

Infine, dovrai registrare la classe sopra nella tua classe di avvio ( Startup.cso Global.asax.cs, a seconda che tu stia utilizzando o meno il modello di avvio OWIN).

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

Questo approccio - insieme ai suoi pro e contro - è ulteriormente spiegato in questo post che ho scritto sul mio blog.


1
buona cosa. ma questa funzionalità è già integrata con vs2015. se crei il progetto webapi asp.net, eseguirà automaticamente tutto il codice della piastra della caldaia per te.
suomi-dev,

@Darkseal potresti per favore approfondire un po '"può essere molto difficile da mantenere e testare"? (Ho letto il tuo post sul blog) Ho usato WebAPI2 e mi piace come funziona. Tuttavia non riesco a capire il "vero grande vantaggio" oltre ad averlo "il modo comune di fare le cose". Avere controller MVC classici che restituiscono stringhe serializzate "manualmente" è abbastanza semplice. L'aggiunta di un interruttore json / xml con il verbo http Accept non richiede molto. Tutto ciò che potrebbe essere racchiuso in un bel metodo di utilità. Grazie.
ValGe

2
@ValGe, vedi la risposta @ manish-jain sopra. In poche parole, Controllerrestituire una stringa serializzata Json avvolta all'interno di una stringa ActionResultè sicuramente più difficile da testare e mantenere di una ApiControllerche può essere impostata per restituire direttamente un elenco di [Serializable]elementi. Qualsiasi metodo di test sarebbe molto più semplice da scrivere, perché non dovrai de-serializzare manualmente ogni volta: lo stesso si può dire per quasi tutte le attività di integrazione di sistema con ASP.NET o altri framework. Controllerssono fantastici, ma ApiControllerssono più adatti per le attività RESTful, almeno in .NET Framework 4.x
Darkseal

1

Ogni metodo nell'API Web restituirà i dati (JSON) senza serializzazione.

Tuttavia, al fine di restituire i dati JSON nei controller MVC, imposteremo il tipo di risultato dell'azione restituito su JsonResult e chiameremo il metodo Json sul nostro oggetto per assicurarci che sia compresso in JSON.


1

La differenza principale è: l'API Web è un servizio per qualsiasi client, qualsiasi dispositivo e il controller MVC serve solo il suo client. Lo stesso perché è la piattaforma MVC.


-1

È abbastanza semplice decidere tra i due: se stai scrivendo un'applicazione web / internet / intranet basata su HTML - forse con la chiamata AJAX occasionale che restituisce json qua e là - resta con MVC / Controller. Se si desidera fornire un'interfaccia basata sui dati / REST a un sistema, utilizzare WebAPI. È possibile combinare entrambi, ovviamente, con un ApiController per soddisfare le chiamate AJAX da una pagina MVC. Fondamentalmente controller è utilizzato per mvc e api-controller è utilizzato per Rest-API è possibile utilizzare entrambi nello stesso programma di cui hai bisogno

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.