Controllers and Controller Actions in MVC Applications

Introduction

The ASP.NET MVC framework maps URLs to classes that are referred to as controllers. Controllers process incoming requests, handle user input and interactions, and execute appropriate application logic. A controller class typically calls a separate view component to generate the HTML markup for the request.

Note

To run the example code in this topic, you need the ASP.NET MVC Preview 3 release. You can download the preview release from the ASP.NET Web site.

The base class for all controllers is the Controller class, which provides general MVC handling. The Controller class implements the IController, IActionFilter, and IDisposable interfaces.

Classes that derive from Controller are responsible for the following processing stages:

  • Locating the appropriate action method to call and validating that it can be called.

  • Getting the values to use as the action method's arguments.

  • Handling all errors that might occur during the execution of the action method.

  • Providing the default WebFormViewFactory class for rendering ASP.NET page types (views).

    Note

    To help secure access to controllers and controller actions, you can use the PrincipalPermissionAttribute class.

All controller classes must be named by using the "Controller" suffix. The following example shows the sample controller class, which is named HomeController. This controller class contains action methods and provides methods for rendering view pages.

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index()
        ViewData("Title") = "Home Page"
        ViewData("Message") = "Welcome to ASP.NET MVC!"

        Return View()
    End Function

    Function About()
        ViewData("Title") = "About Page"

        Return View()
    End Function
End Class
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Title"] = "Home Page";
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        ViewData["Title"] = "About Page";

        return View();
    }
}

Action Methods

In ASP.NET applications that do not use the MVC framework, user interaction is organized around pages, and around raising and handling events from those pages. In contrast, user interaction with ASP.NET MVC applications is organized around controllers and action methods. The controller defines action methods. Controllers can include as many action methods as needed.

Action methods typically have a one-to-one mapping with user interactions. Examples of user interactions include entering a URL into the browser, clicking a link, and submitting a form. Each of these user interactions results in a request being sent to the server. In each case, the URL of the request includes information that the MVC framework uses to invoke an action method.

For example, when a user enters a URL into the browser, the MVC application uses routing rules that are defined in the Global.asax file to parse the URL and to determine the path of the controller. The controller then determines the appropriate action method to handle the request.

By default, the URL of a request is treated as a sub-path that includes the controller name followed by the action name. For example, if a user enters the URL http://contoso.com/MyWebSite/Products/Categories, the sub-path is /Products/Categories. The default routing rule treats "Products" as the name of the controller and "Categories" as the name of the action. Therefore, the routing rule invokes the Categories method of the Products controller in order to process the request. If the URL ends with /Products/Detail/5, the default routing rule treats "Detail" as the name of the action, and the Detail method of the Products controller will be invoked to process the request. By default, the value "5" in the URL will be passed to the Detail method as a parameter.

The following example shows a controller class that has a controller action.

Public Class MyController
    Inherits System.Web.Mvc.Controller

    Function Hello()
        Return View("HelloWorld")
    End Function
End Class
public class MyController : Controller
{
    public ActionResult Hello()
    {
        return View("HelloWorld");
    }
}

ActionResult Return Type

All action methods must return an instance a class that is derived from ActionResult. The ActionResult class is the base for all action results. However, there are different action result types, depending on the action that the action method is taking. For example, the most common action is to call the View method. The View method returns an instance of the ViewResult class, which is derived from ActionResult.

The following list shows the built-in action result types.

  • ViewResult. Returned by the View method.

  • RedirectToRouteResult. Returned by the RedirectToAction and RedirectToRoute methods.

  • RedirectResult. Returned by the Redirect method.

  • ContentResult. Returned by the Content method.

  • JsonResult. Return by the Json method.

  • EmptyResult. Returned if the action method must return a null result.

Marking Public Methods as Non-Action Methods

The MVC framework treats all public methods of a controller class as action methods. Therefore, if your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonAction attribute.

Action Method Parameters

By default, the values for action method parameters are retrieved from the request's data collection. The data collection includes name/values pairs for form data, query string values, and cookie values.

The controller class locates the action method and determines any parameter values for the action method, based on the RouteData instance and on the form data. If the parameter value cannot be parsed, and if the type of the parameter is a reference type or a nullable value type, null is passed as the parameter value. Otherwise, an exception is thrown.

There are several ways to access URL parameter values within the action methods of controller classes. The Controller base class exposes a set of Request and Response objects that can be accessed within an action method. These objects have the same semantics as the HttpRequest and HttpResponse objects that are already a part of ASP.NET. However, the Controller class's Request and Response objects are based on the System.Web.HttpRequestBase and System.Web.HttpResponseBase abstract classes instead of being sealed classes. These base classes make it easy to create mock objects, which makes it easy to create unit tests for controller classes.

The following example shows how to use the Request object to retrieve a query-string value named id.

Public Sub Detail()
    Dim id As Integer = Convert.ToInt32(Request("id"))
End Sub
public void Detail()
{
    int id = Convert.ToInt32(Request["id"]);
}

Automatically Mapping Action-Method Parameters

The ASP.NET MVC framework can automatically map URL parameter values to parameter values for action methods. By default, if an action method takes a parameter, the MVC framework examines incoming request data and determines whether the request contains an HTTP request value with the same name. If so, the request value is automatically passed to the action method.

The following example shows a variation of the previous example. In this variation, the id parameter is assumed to map to a value in the request that is also named id. Because of this automatic mapping, the action method does not have to include code to get a parameter value from the request, and the parameter value is therefore easier to use.

Public Function Detail(ByVal id As Integer) 
    ViewData("DetailInfo") = id 
    Return View("Detail") 
End Function 
public ResultAction Detail(int id)
{
    ViewData["DetailInfo"] = id;
    return View("Detail");
}

You can also embed parameter values as part of the URL instead of as query-string values. For example, instead of using the URL with a query string such as /Products/Detail?id=3, you can use a URL like /Products/Detail/3.

The default route-mapping rule has the format /{controller}/{action}/{id}. If there is a URL sub-path after the controller and action names in the URL, it is treated as a parameter named id, and is automatically passed to the action method as a parameter value.

The MVC framework also supports optional arguments for action methods. Optional parameters in the MVC framework are handled by using nullable-type arguments for controller action methods. For example, if a method can take a date as part of the query string but you want to default to today's date if the query string parameter is missing, you can use code like that in the following example:

Public Function ShowArticles(ByVal date As DateTime?)
    If Not date.HasValue Then
        date = DateTime.Now
    End If
    ' ...
End Function
public ActionResult ShowArticles(DateTime? date)
{
    if(!date.HasValue)
    {
        date = DateTime.Now;
    }
    // ...
}

If the request included a value for the date parameter, that value would be passed to the ShowArticles method. If the request did not include a value for this parameter, the argument would be null, and the controller can take whatever actions that are required in order to handle the missing parameter.

This topic is ASP.NET Extensions documentation and is unsupported by Microsoft. Blank topics are included as placeholders and existing content is subject to change in future releases.