401

I've been playing around with ASP.NET MVC 4 beta and I see two types of controllers now: ApiController and Controller.

I'm little confused at what situations I can choose a particular controller.

For ex: If I want to return a view then I've to use ApiController or the ordinary Controller? I'm aware that the WCF Web API is now integrated with MVC.

Since now we can use both controllers can somebody please point at which situations to go for the corresponding controller.

gideon
  • 19,329
  • 11
  • 72
  • 113
VJAI
  • 32,167
  • 23
  • 102
  • 164
  • 33
    Important: ASPNET Core has 'merged' `ApiController` and `Controller` so if you're using the newer .NET you don't need to worry about ApiController anymore - https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api – Simon_Weaver Dec 30 '16 at 22:22
  • 4
    Glad they did! I predicted this long back by the way http://prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi – VJAI Jan 01 '17 at 08:03
  • 2
    "_Mark and Ted are great friends. They usually fill their dinner table with interesting discussions.. mostly technical!_" Nobody expects the highly technical comic. ;^) – ruffin Aug 19 '20 at 19:07

8 Answers8

402

Use Controller to render your normal views. ApiController action only return data that is serialized and sent to the client.

here is the link

Quote:

Note If you have worked with ASP.NET MVC, then you are already familiar with controllers. They work similarly in Web API, but controllers in Web API derive from the ApiController class instead of Controller class. The first major difference you will notice is that actions on Web API controllers do not return views, they return data.

ApiControllers are specialized in returning data. For example, they take care of transparently serializing the data into the format requested by the client. Also, they follow a different routing scheme by default (as in: mapping URLs to actions), providing a REST-ful API by convention.

You could probably do anything using a Controller instead of an ApiController with the some(?) manual coding. In the end, both controllers build upon the ASP.NET foundation. But having a REST-ful API is such a common requirement today that WebAPI was created to simplify the implementation of a such an API.

It's fairly simple to decide between the two: if you're writing an HTML based web/internet/intranet application - maybe with the occasional AJAX call returning json here and there - stick with MVC/Controller. If you want to provide a data driven/REST-ful interface to a system, go with WebAPI. You can combine both, of course, having an ApiController cater AJAX calls from an MVC page.

To give a real world example: I'm currently working with an ERP system that provides a REST-ful API to its entities. For this API, WebAPI would be a good candidate. At the same time, the ERP system provides a highly AJAX-ified web application that you can use to create queries for the REST-ful API. The web application itself could be implemented as an MVC application, making use of the WebAPI to fetch meta-data etc.

Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
Andre Loker
  • 8,368
  • 1
  • 23
  • 36
  • 10
    Note: since your data will be sent over the wire, how will it be formatted? The way data that an ApiController returns is formatted is determined by content negotiation, and GlobalConfiguration.Configuration.Formatters... link: http://blogs.msdn.com/b/kiranchalla/archive/2012/02/25/content-negotiation-in-asp-net-mvc4-web-api-beta-part-1.aspx – Tim Lovell-Smith Dec 17 '12 at 20:02
  • 1
    Is it correct to say that Web API is a common Platform for website, mobile etc? and we could use Class Library instead of Web API ? – Imad Alazani Sep 11 '13 at 06:34
  • Thanks @TimLovell-Smith for your note, because for me Andre doesn't answer the question : as a Controller can also return data, it doesn't explain why ApiController exists and is useful. – JYL Sep 11 '13 at 18:01
  • @JYL Would I be right in thinking a) ApiController doesn't let you return views? It seems clear b) ApiController is more optimized [usability, perf] for that scenario of returning data, not views. See e.g. Manish's answer. – Tim Lovell-Smith Sep 11 '13 at 20:25
  • 2
    @JYL I augmented my answer to provide more detailed information. – Andre Loker Sep 12 '13 at 07:34
  • @AndreLoker how would you separate the controllers mapping-wise and internal structure-wise (trying to maintain good quality in my first web-app project)? Thanks. – Johnny Aug 30 '15 at 12:46
  • @StasS What exactly do you want to know? In general, it depends on the project size. For the WebAPI Part I'd start with "one controller per resource type" (or aggregate roots if you're familiar with domain driven design): e.g. an OrdersController that handles REST requests like `/orders`, `/orders/17`, `/orders/17/lines` etc. Typically I use a RoutePrefixAttribute (e.g. `[RoutePrefix("api/v1/orders")]`). Currently, I'm mostly developing single-page applications that barely use any MVC Controller at all - it's mostly WebAPI. – Andre Loker Aug 31 '15 at 12:18
  • @AndreLoker great, thanks. Thats what I wanted to know :) And if you have *view* related orders url mapping, how would you structure that? – Johnny Aug 31 '15 at 15:13
  • @StasS I'm not sure I understood the question. What do you mean with "view related orders url mapping"? – Andre Loker Sep 01 '15 at 06:25
  • @AndreLoker controller methods (the url mappers) that return *view* and not *json*. – Johnny Sep 03 '15 at 15:20
  • 2
    I didn't really understand when you said *"providing a REST-ful API by convention"*. How does it provide REST-ful API? Does it not depend on what data you return from the API? There is nothing in the controller which forces (or even facilitate) the API to be REST-ful. – Nawaz Jan 23 '16 at 15:38
  • One nice thing about `Controllers` is they can bind multiple parameters automatically where web api wants a complex object. – xr280xr Sep 09 '21 at 02:26
211

Which would you rather write and maintain?

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();
  }
}
Matt
  • 74,352
  • 26
  • 153
  • 180
Manish Jain
  • 9,569
  • 5
  • 39
  • 44
  • 8
    It's a good point but ApiController is more than just JSON serialization. It also takes care of looking at the request and returning XML if that's the accept type. – Jake Almer Mar 17 '16 at 13:32
  • 14
    If you use asp.net core, all of them are derived from `Controller` class. – Tân Sep 28 '16 at 16:59
  • 4
    This seems old examples, Now we dont need to worry about `ApiController` just `: Controller` works, can you add new dot net core Controller example too – Ashish Kamble Jun 12 '19 at 04:59
  • @AshishKamble, Instead of ApiController, ControllerBase is now used. – Vladimir Shiyanov Jul 12 '19 at 13:53
  • 1
    Honestly, I'd rather have the `Json()` version. It's clearer and more explicit. I don't like a load of black magic in trying to figure out how my code is going to respond to a request. – Jez Nov 07 '19 at 12:18
34

I love the fact that ASP.NET Core's MVC6 merged the two patterns into one because I often need to support both worlds. While it's true that you can tweak any standard MVC Controller (and/or develop your own ActionResult classes) to act & behave just like an ApiController, it can be very hard to maintain and to test: on top of that, having Controllers methods returning ActionResult mixed with others returning raw/serialized/IHttpActionResult data can be very confusing from a developer perspective, expecially if you're not working alone and need to bring other developers to speed with that hybrid approach.

The best technique I've come so far to minimize that issue in ASP.NET non-Core web applications is to import (and properly configure) the Web API package into the MVC-based Web Application, so I can have the best of both worlds: Controllers for Views, ApiControllers for data.

In order to do that, you need to do the following:

  • Install the following Web API packages using NuGet: Microsoft.AspNet.WebApi.Core and Microsoft.AspNet.WebApi.WebHost.
  • Add one or more ApiControllers to your /Controllers/ folder.
  • Add the following WebApiConfig.cs file to your /App_Config/ folder:

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

Finally, you'll need to register the above class to your Startup class (either Startup.cs or Global.asax.cs, depending if you're using OWIN Startup template or not).

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

This approach - together with its pros and cons - is further explained in this post I wrote on my blog.

Darkseal
  • 9,205
  • 8
  • 78
  • 111
  • 1
    good thing. but this functionality is already built in with vs2015. if you create webapi asp.net project, it will automaitcally do all boiler plate code for you. – suomi-dev Sep 16 '18 at 08:43
  • @Darkseal could you please elaborate a bit on "it can be very hard to maintain and to test"? (I have read your blog post) I have used WebAPI2 and I like how it works. However I can't figure out the "real big benefit" besides having it "the common way of doing things". Having classic MVC controllers returning "manually" serialized strings is easy enough. Adding a json/xml switch with http Accept verb doesn't take much. All that could be wrapped into a nice utility method.Thanks. – ValGe Jul 06 '19 at 07:16
  • 2
    @ValGe , see @manish-jain answer above. In a nutshell, a `Controller` returning a Json-serialized string wrapped within an `ActionResult` is definitely harder to test and mantain than an `ApiController` which can be set to directly return a list of `[Serializable]` items. Any test method would be much easier to write, because you won't have to de-serialize manually each time: the same can be said for nearly any system integration task with ASP.NET or other frameworks. `Controllers` are great, but `ApiControllers` are better suited for RESTful tasks, at least in .NET Framework 4.x – Darkseal Jul 07 '19 at 01:18
11

Quick n Short Answer

If you want to return a view, you should be in "Controller".

Normal Controller - ASP.NET MVC: you deal with normal "Controller" if you are in ASP.net Web Application. You can create Controller-Actions and you can return Views().

ApiController Controller: you create ApiControllers when you are developing ASP.net REST APIs. you can't return Views (though you can return Json/Data for HTML as string). These apis are considered as backend and their functions are called to return data not the view

More Details here

rene
  • 41,474
  • 78
  • 114
  • 152
Imran
  • 254
  • 3
  • 14
1

Every method in Web API will return data (JSON) without serialization.

However, in order to return JSON Data in MVC controllers, we will set the returned Action Result type to JsonResult and call the Json method on our object to ensure it is packaged in JSON.

1

The main difference is: Web API is a service for any client, any devices, and MVC Controller only serve its client. The same because it is MVC platform.

ANJYR
  • 2,583
  • 6
  • 39
  • 60
0

enter image description here

If you create a new web application in latest framework 4.7.2 you will both of them to be configured by default and can build you application on that

enter image description here

Rajesh Kumar
  • 69
  • 1
  • 8
-3

In Asp.net Core 3+ Vesrion

Controller: If wants to return anything related to IActionResult & Data also, go for Controllercontroller

ApiController: Used as attribute/notation in API controller. That inherits ControllerBase Class

ControllerBase: If wants to return data only go for ControllerBase class