Click here to Skip to main content
15,881,715 members
Articles / Web Development / ASP.NET
Tip/Trick

Understanding the IController and ControllerBase in ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
9 May 2013CPOL3 min read 73.8K   15   2
The tip describes about the IController interface and the ControllerBase class.

Introduction

Controllers in MVC are responsible for responding to user interactions, often making changes to the Model in response to user input. In short, controllers in the MVC pattern are concerned with the flow of the application, processing of the incoming data and providing data going out to the relevant View.

Whenever we add a controller to our MVC project, Visual Studio, creates a class whose name is suffixed with "Controller". This newly created class inherits from Controller class, which makes it to behave as a controller. Alternatively, we can also create a controller by inheriting from ControllerBase class or by implementing the IController interface. This is possible as, Controller class inherits ControllerBase class, which in turn implements the methods of IController interface. Let's go through ControllerBase class and IController interface and find out what methods each of them offer.

IController interface

IController interface, sole purpose is to execute some code when a request is made to a controller. This is how the interface looks like:

Note: We can get the source code from  aspnetwebstack.codeplex.com/

C#
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// See License.txt in the project root for license information.

using System.Web.Routing;
namespace System.Web.Mvc
{
    public interface IController
    {
        void Execute(RequestContext requestContext);
    }
}

IController interface exposes Execute() method, that gets executed when a request is made for the controller. It accepts an object of RequestContext class, which encapsulates information about an HTTP request that matches a defined route, using the HttpContext and RouteData properties.

Thus, we can create a controller by implementing the IController and implement its Execute() method to do some work. For example the below MyCustomController class, implements IController and gives a body to the Execute() method.

C#
public class MyCustomController : IController
{
    public void Execute(RequestContext requestContext)
    {
        string controller = requestContext.RouteData.Values["controller"] as string;   
        string action = requestContext.RouteData.Values["action"] as string;   
        requestContext.HttpContext.Response.Write(string.Format("Controller name - {0}", controller));
        requestContext.HttpContext.Response.Write(string.Format("Action name - {0}", action)); 
    }
}

Over here, we are fetching the controller and action names from the route values collection and to keep the example simple directly writing it to the response.


ControllerBase class

The abstract ControllerBase class represents the base class for all MVC controllers. It implements the IController interface's, Execute() method which executes the specified request context. This is how the class looks like :

C#
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// See License.txt in the project root for license information.
public abstract class ControllerBase : IController
{
    protected virtual void Execute(RequestContext requestContext)
    {
        if (requestContext == null)
        {
            throw new ArgumentNullException("requestContext");
        }
        if (requestContext.HttpContext == null)
        {
            throw new ArgumentException(
              MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, 
              "requestContext");
        }
        VerifyExecuteCalledOnce();
        Initialize(requestContext);
        using (ScopeStorage.CreateTransientScope())
        {
            ExecuteCore();
        }
    }
    protected abstract void ExecuteCore();
    protected virtual void Initialize(RequestContext requestContext)
    {
        ControllerContext = new ControllerContext(requestContext, this);
    }
    internal void VerifyExecuteCalledOnce()
    {
        if (!_executeWasCalledGate.TryEnter())
        {
            string message = String.Format(CultureInfo.CurrentCulture, 
              MvcResources.ControllerBase_CannotHandleMultipleRequests, GetType());
            throw new InvalidOperationException(message);
        }
    }
    void IController.Execute(RequestContext requestContext)
    {
        Execute(requestContext);
    }
}

The ControllerBase class acts as a wrapper on top of the IController interface. The Execute() method of ControllerBase class is responsible for creating the ControllerContext, which provides the MVC specific context for the current request much in the same way that an instance of HttpContext provides the context for ASP.NET, providing request and response, URL and server information, among other elements.

We can see that, ControllerBase class provides an implementation of Execute(), but then it has another definition for IController.Execute(), so the question is why is it so ?

By default, normally implemented interface method is public and is not virtual or abstract, so you can't override it in derived classes. So if we are creating a new Execute() method inside ControllerBase class, it wouldn't be accessible through the IController interface by default when its own Execute() method is to be called.

But by creating a new, protected virtual Execute() method inside ControllerBase class, which we will be calling from the explicitly implemented interface method (IController.Execute()), allows derived classes (Controller class) to override the ControllerBase class Execute() method without breaking the interface implementation.

Thus, we can create a controller by implementing the ControllerBase and override it's ExecuteCore() method to do some work. For example the below MyCustomController class, inherits ControllerBase and gives a body to the ExecuteCore() method.

C#
public class MyCustomController : ControllerBase 
{
    protected override void ExecuteCore()
    {
        string controllername = ControllerContext.RouteData.Values["controller"].ToString();
        string actionName = ControllerContext.RouteData.Values["action"].ToString();
        this.ControllerContext.HttpContext.Response.Write(
             string.Format("Controller name - {0}", controllername));
        this.ControllerContext.HttpContext.Response.Write(
             string.Format("Action name - {0}", actionName));
    }
}

Over here, we are fetching the controller and action names from the route values collection and to keep the example simple directly writing it to the response.

Controller's that implement IController or inherit ControllerBase directly, have to write down there own implementations for mapping the request URL with the execution of the appropriate action. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Mindfire Solutions
India India
Software developer, working at Mindfire Solutions, having hands on experience in both Windows and web application using C#, ASP.NET, ASP.NET MVC.

Comments and Discussions

 
GeneralNice Post, My Vote of 5 Pin
Subhajit Ray11-May-15 0:46
Subhajit Ray11-May-15 0:46 
GeneralMy vote of 5 Pin
LogeshKumarK9-May-13 22:13
LogeshKumarK9-May-13 22:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.