title: What is the difference between MVC Controller and Web API Controller in ASP.NET MVC 6?
body: <p>In ASP.NET 5 MVC 6 Microsoft merged the normal MVC controller class (<code>Controller</code>) with the Web Api controller class (<code>ApiController</code>). Now there is just a <code>Controller</code> class to inherit from, which includes the features of WebApi too.</p>
  
  <p>So now it is not as simple to distinguish MVC and WebApi controllers. Both inherit from the <code>Controller</code> class. The only difference I can spot is that the routing information of WebApi is still provided by the attributes <code>HttpGet</code>, <code>HttpPost</code>, <code>HttpPut</code> and <code>HttpDelete</code>. But now it is possible to do the same with MVC controllers using attribute routing, just with different attributes. </p>
  
  <p>Even the features seem to have merged. MVC controllers support now content negotiation too. </p>
  
  <p>The concrete questions are: </p>
  
  <p>Is there still a real difference, or is it just the way the routes are specified? Which way is now the preferred one to create web apps? </p>
  
  <p>(Almost) empty MVC controller:</p>
  
  <pre><code>public class HomeController : Controller
  {
      public List&lt;Person&gt; Index()
      {
          return new List&lt;Person&gt;()
          {
              new Person() {Firstname = "test1", Lastname = "test2"},
              new Person() {Firstname = "test3", Lastname = "test4"}
          };
      }
  
      public IActionResult About()
      {
          ViewData["Message"] = "Your application description page.";
  
          return View();
      }
  
      public IActionResult Contact()
      {
          ViewData["Message"] = "Your contact page.";
  
          return View();
      }
  
      public IActionResult Error()
      {
          return View("~/Views/Shared/Error.cshtml");
      }
  }
  </code></pre>
  
  <p>(Almost) empty WebApi controller:</p>
  
  <pre><code>[Route("api/[controller]")]
  public class ValuesController : Controller
  {
      // GET: api/values
      [HttpGet]
      public IEnumerable&lt;Person&gt; Get()
      {
          return new List&lt;Person&gt;()
          {
              new Person() {Firstname = "test1", Lastname = "test2"},
              new Person() {Firstname = "test3", Lastname = "test4"}
          };
      }
  
      // GET api/values/5
      [HttpGet("{id}")]
      public string Get(int id)
      {
          return "value";
      }
  
      // POST api/values
      [HttpPost]
      public void Post([FromBody]string value)
      {
      }
  
      // PUT api/values/5
      [HttpPut("{id}")]
      public void Put(int id, [FromBody]string value)
      {
      }
  
      // DELETE api/values/5
      [HttpDelete("{id}")]
      public void Delete(int id)
      {
      }
  }
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p>If you want to try if content negotiation works, you have to include this code into your Startup.ConfigureServices method, because per default the return type is JSON only.</p>
  
  <pre><code>services.Configure&lt;MvcOptions&gt;(options =&gt;
  {
      options.AddXmlDataContractSerializerFormatter();
  });
  </code></pre>