Table of contents

Last updated .

< Previous chapterNext chapter >

Controllers

Controllers are at the heart of the MVC framework. They tie together views and models and accept input from the user. With that, the controller can respond accordingly, usually by updating the UI, and sometimes the model. There will be many controller classes in an MVC application. Which class is going to handle a particular request is determined by the URL and the routing mechanism. In MVC, there is no direct relation between a URL and a file on disc. The controller class determines dynamically which view to render. You can think of the browser request / URL as a method call on a controller.

The basics

As the previous chapter demonstrated, a controller class is located in a subfolder of the Controllers folder. This is a convention, and is an example of the "convention over configuration" principle that underlies ASP.Net MVC. The principle means that configuration is kept at a minimum, and instead, sensible conventions apply. One convention is that, by default, controllers are found in the Controllers folder. Another convention is that the name of a controller class must end with "Controller".

A controller class inherits from System.Web.Mvc.Controller, which offers a lot of functionality to the inheriting class. A public method on a controller class is termed an "action", meaning you can invoke it from the web via some URL to perform an action. When a request arrives at the server, the URL determines which controller class to instantiate and which action to call. The relationship between controller, action and a URL is this: "http://baseaddress/controller/action".

A controller will normally let a view render the UI by returning a ViewResult instance (I'll get to that), but to keep things simple right now, the action methods will still just return strings. I have modified the HomeController class by adding two other actions. The actions now return information about their name and any parameters:

Controllers/HomeController.cs
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
using Microsoft.AspNet.Mvc; namespace MVCTutorial.Controllers { public class HomeController : Controller { public string Index() { return "Hello from Index!"; } public string SomeAction() { return "Hello from SomeAction"; } public string OtherAction(int id) { return string.Format("Hello from OtherAction, id is {0}", id); } } }

Requesting the URL http://localhost:[port]/home/index causes the index action of the HomeController to be invoked. The same happens with http://localhost:[port]/home and http://localhost:[port], attesting to the fact that HomeController is the default controller, and Index is the default action of the HomeController.

HomeController.Index
HomeController.Index

Requesting http://localhost:[port]/home/someaction causes the SomeAction method to be called.

HomeController.SomeAction
HomeController.SomeAction

The OtherAction method takes an int argument. You can pass that value in the URL as http://localhost:[port]/home/otheraction/17 or http://localhost:[port]/home/otheraction?id=17. If no value is specified, it defaults to 0. The transformation of a HTTP request value into a method parameter is perfomed by ASP.Net's model binding feature.

HomeController.Index
HomeController.Index

Routing

The purpose of routing is to map incoming requests, together with any parameters, to controller actions. The routing is set up during application start. In chapter 1, we already added code in the Startup class to set up a default route:

Startup.cs
1:
2:
3:
4:
5:
6:
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });

To define a route, you specify a name for it and a template, which is a string with the pattern of the URL. You can define as many routes as you want - in this case there is only the one. The particular route we have made so far will map any request to a controller method, as long as the request is of the form baseaddress/foo/bar. Note that, by convention, the name of a controller class has a "Controller" suffix, e.g. "HomeController". That suffix is not supposed to be part of the URL. In addition, the configured route allows an optional id parameter to be passed, as in the above example. So, with the URL pattern {controller=foo}/{action=bar}/{param?}, it maps requests such as baseaddress/foo/xyz or baseaddress/foo/xyz/17 to a xyz method of a fooController class. A request of baseaddress/abc/index would cause the index method of a abcController class to be called.

A lot more can be said about routing and I will come back to it with a more in-depth treatment.

< Previous chapterNext : Views >


2016 by Niels Hede Pedersen Linked in