ASP.NET MVC relies on certain conventions (both naming and placement) to properly route requests and return views and view models. One of the ways it allows us programmers to manage these conventions is with the use of Areas, which are modules within an MVC project that exist with their own controllers, views, and actions.
Let's learn how we can add Areas to an existing project, and what their separation from the main project allows us to do.
What are Areas?
Areas are pieces of an MVC application that do not use the main controllers, actions, and views; rather, they mimic this structure within a specific subfolder in the project directory. In general, we use Areas to split out "semi-independent" sections of our applications, so that they can be maintained and upgraded separately from the rest of the app. Having an area has no functional impact (other than routing, which we will discuss in a bit).
In Visual Studio, we can scaffold an area by right-clicking on the project file and selecting Add -> Area.
As you might have guessed, Areas are especially useful in larger applications, where these semi-independent portions of the app might be greater in both scope and number.
Registering an Area
Notice that, in the earlier screenshot, the Billing area is a subfolder under the Areas folder. This structure is intentional; an Area by default must exist in the Areas folder and be named appropriately. This is in keeping with MVC's general Separation of Concerns ideology.
Under the Billing folder are folders for Controllers, Models, and Views, as well as another file called BillingAreaRegistration.cs. This file is what registers the new Billing area with the ASP.NET MVC framework. Here's what it looks like:
namespace MVCAreasDemo.Areas.Billing
{
public class BillingAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Billing";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Billing_default",
"Billing/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
The important part of this file is the RegisterArea()
method. In that method, we set up the routes for the area, just like we do for the general application in the RouteConfig
class. However, just having this registration isn't enough. We also need to make the following call in our Global.asax file:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); //Registers all Areas in the Areas folder
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
With both of those pieces, the Billing area becomes accessible in our MVC app.
Controllers in Areas
Notice that any route that directs to this new Billing area must begin with the "Billing" area name. This is so the convention-based routing system can identify which Area to route to when receiving a request like this.
Let's add a simple controller BillingMainController
to the Billing area.
public class BillingMainController : Controller
{
// GET: Billing/BillingMain
public ActionResult Index()
{
return View();
}
}
Now that looks pretty darn similar to any other controller we might add to the main MVC app. Areas are only distinguished from the rest of an MVC application by their folder placement and routing; otherwise they behave the same way. But how can we create links to actions in Areas?
Linking to Area Actions
If we want to create links on a Razor view to a controller action in an Area, we need to use an additional parameter called Area:
@Html.ActionLink("BillingMain", "Index", new { Area = "Billing" })
If we click on that link, the follow page shows up:
Summary
Areas in ASP.NET MVC apps are used to give better structure to our large applications. They exist as modules independent of the main app, with their own controllers, folders, routes, and views. The only setup we need to do is to register the area with the framework, both in the Area's Registration file and in our Global.asax.
Please feel free to take a look at the sample project I whipped up over on GitHub. Pull requests and suggestions are always welcome!
Happy Coding!