Diferença entre ApiController e Controller no ASP.NET MVC

343

Venho brincando com o ASP.NET MVC 4 beta e agora vejo dois tipos de controladores: ApiControllere Controller.

Estou um pouco confuso em que situações posso escolher um controlador em particular.

Por exemplo: se eu quiser retornar uma visualização, devo usar ApiControllerou o comum Controller? Estou ciente de que a API da Web do WCF agora está integrada ao MVC.

Como agora podemos usar os dois controladores, alguém pode apontar em quais situações o controlador correspondente será direcionado.

VJAI
fonte
23
Importante: o ASPNET Core foi 'mesclado' ApiControllere, Controllerportanto, se você estiver usando o .NET mais recente, não precisará mais se preocupar com o ApiController - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver
2
Ainda bem que eles fizeram! Eu previ isso há muito tempo, pela maneira como prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Respostas:

356

Use o Controller para renderizar suas visualizações normais. A ação ApiController retorna apenas dados serializados e enviados ao cliente.

aqui está o link

Citar:

Nota Se você trabalhou com o ASP.NET MVC, já está familiarizado com os controladores. Eles funcionam da mesma forma na Web API, mas os controladores da Web API derivam da classe ApiController em vez da classe Controller. A primeira grande diferença que você notará é que as ações nos controladores de API da Web não retornam visualizações, eles retornam dados.

Os ApiControllers são especializados em retornar dados. Por exemplo, eles cuidam da serialização transparente dos dados no formato solicitado pelo cliente. Além disso, eles seguem um esquema de roteamento diferente por padrão (como em: mapear URLs para ações), fornecendo uma API REST-ful por convenção.

Você provavelmente poderia fazer qualquer coisa usando um Controller em vez de um ApiController com a codificação manual (?). No final, os dois controladores se baseiam na base do ASP.NET. Mas ter uma API REST-ful é um requisito tão comum hoje em dia que a WebAPI foi criada para simplificar a implementação de uma API desse tipo.

É bastante simples decidir entre os dois: se você estiver escrevendo um aplicativo Web / Internet / Intranet baseado em HTML - talvez com uma chamada AJAX ocasional retornando json aqui e ali - fique com o MVC / Controller. Se você deseja fornecer uma interface orientada a dados / REST-ful a um sistema, acesse WebAPI. É possível combinar ambos, é claro, ter um ApiController para atender chamadas AJAX a partir de uma página do MVC.

Para dar um exemplo do mundo real: atualmente, estou trabalhando com um sistema ERP que fornece uma API REST-cheia para suas entidades. Para essa API, o WebAPI seria um bom candidato. Ao mesmo tempo, o sistema ERP fornece um aplicativo Web altamente AJAX-ified que você pode usar para criar consultas para a API REST-ful. O aplicativo da Web em si pode ser implementado como um aplicativo MVC, fazendo uso da WebAPI para buscar metadados, etc.

Andre Loker
fonte
9
Nota: como seus dados serão enviados por cabo, como serão formatados? A forma como os dados que um ApiController retorna são formatados é determinado pela negociação de conteúdo, e GlobalConfiguration.Configuration.Formatters ... link: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith
11
É correto dizer que a API da Web é uma plataforma comum para sites, dispositivos móveis etc? e poderíamos usar a biblioteca de classes em vez da API da Web?
Imad Alazani 11/11/13
Obrigado @ TimLovell-Smith por sua observação, porque para mim Andre não responde à pergunta: como um Controller também pode retornar dados, ele não explica por que o ApiController existe e é útil.
JYL
2
@JYL Aumentei minha resposta para fornecer informações mais detalhadas.
Andre Loker
2
Eu realmente não entendi quando você disse "fornecendo uma API REST-ful por convenção" . Como ele fornece API REST-ful? Não depende de quais dados você retorna da API? Não há nada no controlador que force (ou até facilite) a API a ser REST-ful.
Nawaz
192

Qual você prefere escrever e manter?

ASP.NET MVC

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

API da Web do ASP.NET

public class TweetsController : ApiController {
  // GET: /Api/Tweets/
  public List<Tweet> Get() {
    return Twitter.GetTweets();
  }
}
Manish Jain
fonte
6
É um bom ponto, mas o ApiController é mais do que apenas serialização JSON. Ele também cuida de olhar para a solicitação e retornar XML, se esse for o tipo de aceitação.
Jake Almer
10
Se você usar o núcleo do asp.net, todos eles serão derivados da Controllerclasse.
Tân
2
Isso parece exemplos antigos: agora não precisamos nos preocupar ApiControllerapenas com : Controllertrabalhos, você pode adicionar um novo exemplo de controlador de ponto líquido para o núcleo também
Ashish Kamble
@AshishKamble, em vez de ApiController, ControllerBase agora é usado.
Vladimir Shiyanov 12/07/19
Honestamente, eu prefiro ter a Json()versão. É mais claro e mais explícito. Não gosto de muita magia negra na tentativa de descobrir como meu código responderá a uma solicitação.
Jez
27

Adoro o fato de o MVC6 do ASP.NET Core mesclar os dois padrões em um, porque muitas vezes preciso oferecer suporte aos dois mundos. Embora seja verdade que você pode ajustar qualquer MVC padrão Controller(e / ou desenvolver suas próprias ActionResultclasses) para agir e se comportar como um ApiController, pode ser muito difícil de manter e testar: além disso, ter métodos de Controladores retornando ActionResultmisturados com outros retornar dados brutos / serializados / IHttpActionResultpode ser muito confuso do ponto de vista do desenvolvedor, principalmente se você não estiver trabalhando sozinho e precisar levar outros desenvolvedores a acelerar essa abordagem híbrida.

A melhor técnica que eu vim até agora para minimizar esse problema em aplicativos da Web não-essenciais do ASP.NET é importar (e configurar corretamente) o pacote da API da Web no aplicativo da Web baseado em MVC, para que eu possa ter o melhor de ambos mundos: Controllerspara Views, ApiControllerspara dados.

Para fazer isso, você precisa fazer o seguinte:

  • Instale os seguintes pacotes de API da Web usando o NuGet: Microsoft.AspNet.WebApi.Coree Microsoft.AspNet.WebApi.WebHost.
  • Adicione um ou mais ApiControllers à sua /Controllers/pasta.
  • Adicione o seguinte arquivo WebApiConfig.cs à sua /App_Config/pasta:

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

Por fim, você precisará registrar a classe acima na sua Inicialização classe ( Startup.csou Global.asax.cs, dependendo se você estiver usando o modelo de inicialização OWIN ou não).

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

Essa abordagem - junto com seus prós e contras - é explicada mais detalhadamente neste post que escrevi no meu blog.

Darkseal
fonte
11
coisa boa. mas essa funcionalidade já está integrada no vs2015. se você criar o projeto webapi asp.net, ele fará automaticamente todo o código da placa da caldeira para você.
suomi-dev
@ Darkseal você poderia, por favor, elaborar um pouco sobre "pode ​​ser muito difícil de manter e testar"? (Eu li o seu post no blog) Eu usei o WebAPI2 e gosto de como ele funciona. No entanto, não consigo descobrir o "grande benefício real" além de tê-lo "da maneira comum de fazer as coisas". Ter controladores MVC clássicos retornando seqüências serializadas "manualmente" é bastante fácil. Adicionar uma opção json / xml com http Accept verb não leva muito tempo. Tudo isso pode ser envolvido em um bom método utilitário.
ValGe 06/07/19
2
@ ValGe, veja @ resposta manish-jain acima. Em poucas palavras, o Controllerretorno de uma sequência serializada Json inserida em uma ActionResulté definitivamente mais difícil de testar e manter do que uma ApiControllerque pode ser configurada para retornar diretamente uma lista de [Serializable]itens. Qualquer método de teste seria muito mais fácil de escrever, porque você não precisará desserializar manualmente a cada vez: o mesmo pode ser dito para praticamente qualquer tarefa de integração de sistemas com o ASP.NET ou outras estruturas. Controllerssão grandes, mas ApiControllerssão mais adequados para tarefas RESTful, pelo menos em .NET Framework 4.x
Darkseal
1

Todo método na API da Web retornará dados (JSON) sem serialização.

No entanto, para retornar dados JSON nos controladores MVC, definiremos o tipo de resultado da ação retornado como JsonResult e chamaremos o método Json em nosso objeto para garantir que ele seja empacotado em JSON.

Shailesh Uke
fonte
1

A principal diferença é: Web API é um serviço para qualquer cliente, qualquer dispositivo e o MVC Controller serve apenas a seu cliente. O mesmo porque é a plataforma MVC.

ANJYR - KODEXPRESSION
fonte
-1

É bastante simples decidir entre os dois: se você estiver escrevendo um aplicativo Web / Internet / Intranet baseado em HTML - talvez com uma chamada AJAX ocasional retornando json aqui e ali - fique com o MVC / Controller. Se você deseja fornecer uma interface orientada a dados / REST-ful a um sistema, acesse WebAPI. É possível combinar ambos, é claro, ter um ApiController para atender chamadas AJAX a partir de uma página do MVC. Basicamente, o controlador é usado para mvc e o api-controller é usado para Rest-API. Você pode usar ambos no mesmo programa que sua necessidade


fonte