Diferencia entre ApiController y Controller en ASP.NET MVC

343

He estado jugando con ASP.NET MVC 4 beta y ahora veo dos tipos de controladores: ApiController y Controller.

Estoy un poco confundido sobre qué situaciones puedo elegir un controlador en particular.

Por ejemplo: si quiero devolver una vista, entonces tengo que usar ApiControllero el ordinarioController ? Soy consciente de que la API web de WCF ahora está integrada con MVC.

Como ahora podemos usar ambos controladores, ¿alguien puede señalar qué situaciones elegir para el controlador correspondiente?

VJAI
fuente
23
Importante: ASPNET Core se ha 'fusionado' ApiControllery, Controllerpor lo tanto, si está utilizando el .NET más nuevo, ya no tendrá que preocuparse por ApiController: docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver
2
Me alegro de que lo hicieron! Predecí
VJAI

Respuestas:

356

Utilice el controlador para representar sus vistas normales. La acción ApiController solo devuelve datos que se serializan y se envían al cliente.

aqui esta el link

Citar:

Nota Si ha trabajado con ASP.NET MVC, ya está familiarizado con los controladores. Funcionan de manera similar en la API web, pero los controladores en la API web derivan de la clase ApiController en lugar de la clase Controller. La primera gran diferencia que notará es que las acciones en los controladores de API web no devuelven vistas, sino que devuelven datos.

Los ApiControllers están especializados en devolver datos. Por ejemplo, se encargan de serializar los datos de forma transparente en el formato solicitado por el cliente. Además, siguen un esquema de enrutamiento diferente de forma predeterminada (como en: asignación de URL a acciones), proporcionando una API REST-ful por convención.

Probablemente podría hacer cualquier cosa usando un Controlador en lugar de un ApiController con alguna codificación manual (?). Al final, ambos controladores se basan en la base ASP.NET. Pero tener una API REST-ful es un requisito tan común hoy en día que WebAPI se creó para simplificar la implementación de dicha API.

Es bastante simple decidir entre los dos: si está escribiendo una aplicación web / internet / intranet basada en HTML, tal vez con la llamada ocasional de AJAX que devuelve json aquí y allá, quédese con MVC / Controller. Si desea proporcionar una interfaz basada en datos / REST-ful a un sistema, vaya con WebAPI. Puede combinar ambos, por supuesto, tener un ApiController para atender las llamadas AJAX desde una página MVC.

Para dar un ejemplo del mundo real: actualmente estoy trabajando con un sistema ERP que proporciona una API REST-ful a sus entidades. Para esta API, WebAPI sería un buen candidato. Al mismo tiempo, el sistema ERP proporciona una aplicación web altamente AJAX que puede usar para crear consultas para la API REST-ful. La aplicación web en sí podría implementarse como una aplicación MVC, haciendo uso de WebAPI para obtener metadatos, etc.

Andre Loker
fuente
99
Nota: dado que sus datos se enviarán por cable, ¿cómo se formatearán? La forma en que los datos que devuelve un ApiController se formatean está determinada por la negociación de contenido, y GlobalConfiguration.Configuration.Formatters ... enlace: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith
1
¿Es correcto decir que la API web es una plataforma común para sitios web, dispositivos móviles, etc.? y podríamos usar Class Library en lugar de Web API?
Imad Alazani
Gracias @ TimLovell-Smith por su nota, porque para mí Andre no responde la pregunta: como un controlador también puede devolver datos, no explica por qué existe ApiController y es útil.
JYL
2
@JYL Aumenté mi respuesta para proporcionar información más detallada.
Andre Loker
2
Realmente no entendí cuando dijiste "proporcionar una API REST-ful por convención" . ¿Cómo proporciona la API REST-ful? ¿No depende de qué datos devuelves de la API? No hay nada en el controlador que obligue (o incluso facilite) que la API sea REST-ful.
Nawaz
192

¿Cuál preferirías escribir y mantener?

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
fuente
66
Es un buen punto, pero ApiController es más que solo la serialización JSON. También se encarga de mirar la solicitud y devolver XML si ese es el tipo de aceptación.
Jake Almer
10
Si usa asp.net core, todos ellos se derivan de la Controllerclase.
Tân
2
Esto parece ejemplos antiguos, ahora nosotros no necesita preocuparse por ApiControllersólo : Controllerobras, se puede añadir nuevos puntos ejemplo del controlador de red de núcleo también
Ashish Kamble
@AshishKamble, en lugar de ApiController, ahora se usa ControllerBase.
Vladimir Shiyanov
Honestamente, prefiero tener la Json()versión. Es más claro y más explícito. No me gusta un montón de magia negra al tratar de averiguar cómo responderá mi código a una solicitud.
Jez
27

Me encanta el hecho de que MVC6 de ASP.NET Core fusionó los dos patrones en uno solo porque a menudo necesito admitir ambos mundos. Si bien es cierto que puede ajustar cualquier MVC estándar Controller(y / o desarrollar sus propias ActionResultclases) para actuar y comportarse de la misma manera ApiController, puede ser muy difícil de mantener y probar: además de eso, hacer que los métodos de los Controladores regresen ActionResultmezclados con otros volviendo crudo / serializado /IHttpActionResult puede ser muy confuso desde la perspectiva del desarrollador, especialmente si no está trabajando solo y necesita que otros desarrolladores aceleren con ese enfoque híbrido.

La mejor técnica que he llegado hasta ahora para minimizar ese problema en las aplicaciones web no principales de ASP.NET es importar (y configurar correctamente) el paquete de API web en la aplicación web basada en MVC, para que pueda tener lo mejor de ambos mundos: Controllerspara Vistas, ApiControllerspara datos.

Para hacer eso, debe hacer lo siguiente:

  • Instale los siguientes paquetes de API web con NuGet: Microsoft.AspNet.WebApi.Corey Microsoft.AspNet.WebApi.WebHost.
  • Agregue uno o más ApiControllers a su /Controllers/carpeta.
  • Agregue el siguiente WebApiConfig.cs archivo a su /App_Config/carpeta:

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

Finalmente, deberá registrar la clase anterior en su clase de inicio (ya sea Startup.cso Global.asax.cs, dependiendo de si está utilizando la plantilla de inicio de OWIN o no).

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

Este enfoque, junto con sus ventajas y desventajas, se explica con más detalle en esta publicación que escribí en mi blog.

Darkseal
fuente
1
Buena cosa. pero esta funcionalidad ya está integrada con vs2015. Si crea el proyecto webapi asp.net, automáticamente hará todo el código de la placa de la caldera por usted.
suomi-dev
@Darkseal, ¿podría explicar un poco más sobre "puede ser muy difícil de mantener y probar"? (He leído su publicación de blog) He usado WebAPI2 y me gusta cómo funciona. Sin embargo, no puedo entender el "gran beneficio real" además de tenerlo "la forma común de hacer las cosas". Tener controladores MVC clásicos que devuelven cadenas serializadas "manualmente" es bastante fácil. Agregar un modificador json / xml con http Accept verb no toma mucho. Todo eso podría incluirse en un buen método de utilidad. Gracias.
ValGe
2
@ValGe, vea la respuesta @ manish-jain arriba. En pocas palabras, Controllerdevolver una cadena serializada con Json envuelta dentro de una ActionResultes definitivamente más difícil de probar y mantener que una ApiControllerque se puede configurar para devolver directamente una lista de [Serializable]elementos. Cualquier método de prueba sería mucho más fácil de escribir, ya que no tendrá que deserializar manualmente cada vez: se puede decir lo mismo para casi cualquier tarea de integración del sistema con ASP.NET u otros marcos. Controllersson geniales, pero ApiControllersson más adecuados para tareas RESTful, al menos en .NET Framework 4.x
Darkseal
1

Todos los métodos en la API web devolverán datos (JSON) sin serialización.

Sin embargo, para devolver datos JSON en controladores MVC, estableceremos el tipo de resultado de acción devuelto en JsonResult y llamaremos al método Json en nuestro objeto para asegurarnos de que esté empaquetado en JSON.

Shailesh Uke
fuente
1

La principal diferencia es: Web API es un servicio para cualquier cliente, cualquier dispositivo, y MVC Controller solo sirve a su cliente. Lo mismo porque es la plataforma MVC.

ANJYR - KODEXPRESSION
fuente
-1

Es bastante simple decidir entre los dos: si está escribiendo una aplicación web / internet / intranet basada en HTML, tal vez con la llamada ocasional de AJAX que devuelve json aquí y allá, quédese con MVC / Controller. Si desea proporcionar una interfaz basada en datos / REST-ful a un sistema, vaya con WebAPI. Puede combinar ambos, por supuesto, tener un ApiController para atender las llamadas AJAX desde una página MVC. Básicamente, el controlador se usa para mvc y el controlador api se usa para Rest-API, puede usar ambos en el mismo programa que necesite


fuente