4

Use ASP.NET Core to cut the number of controllers in your web app

If you’ve ever built a Single Page Application on top of ASP.NET, you’ve probably found yourself creating a number of MVC controllers to serve your SPA’s initial views. These views then pull in all of your javascript code and references etc.

In previous versions of ASP.NET, MVC and Web API controllers were separate so you’d often end up with two controllers called the same thing, but in different places.

For example, you might have an Orders MVC controller to serve the main Orders view and an Orders API controller to serve the data which that page uses.

Well hold the phone, in ASP.NET core you can now choose to perform both functions in one controller.

Crossing the streams

In .net core you can use IActionResult as the return type for all of your controller actions irrespective of whether they’re serving data or views.

For example, this action returns an Order.

public class OrderController : Controller {

    public IActionResult ById(string id){
        var order =_orders.Find(id);
        if(order == null){
            return NotFound();
        }
        return Ok(order);
    }
}

IActionResult is super useful because you can easily handle error cases and success cases but stick to one return type.

This example will either return a 404 Not Found result if the order can’t be found, or a 200 status code and the relevant order.

Now what about the Order view? Using .net core you can return the Orders view using the same controller.

public class OrderController : Controller {

    public IActionResult Index(){
        return View();
    }

    public IActionResult ById(string id){
        var order =_orders.Find(id);
        if(order == null){
            return NotFound();
        }
        return Ok(order);
    }
}

Using the standard .net core MVC routing, this will look for a view called Index.cshtml inside of Views/Order.

So how can we hit these two actions?

GET /Order returns Views/Order/Index.cshtml
GET /Order/ById/1 returns the relevant order data (as JSON)

Summary

Declutter your web application. Get rid of those controllers which return a single view for your SPA by moving the action into a .net core controller which also serves your application’s data.

  • That’s interesting and the main point here is that we only have one type of controller not two like before. I wouldn’t go as far as putting those together especially if you like writing RESTful stuff.

  • leedjones

    So you *can*, but should you?

    • Yeah I’ve been pondering that one myself. I think it will ultimately come down to the kind of project you’re working on.

      If you’re building a “public” API that will/could serve different clients then arguably not. You’d want your API controllers to serve that single purpose.

      If however, you’re building an API specifically to support a SPA that you’re also building then the convenience *may* outweigh the negatives.

      As @andrei_dragotoniu:disqus alluded to, more interesting is the fact that they share the same controller so you can use the same ActionFilters irrespective, useful for things like Authorisation.

      It always seemed quite dangerous that you could use an attribute in a controller, get no errors but then discover it did nothing because it was written for the “other” controller type.

  • Pingback: Use ASP.NET Core to cut the number of controllers in your web app – ASP.NET Core MVC Tips()