Areor i ASP.NET MVC 2

När man utvecklar större webbplatser så brukar det underlätta om man kan dela upp dessa i olika areor där varje area kan handla om ett eget ämne. I ASP.NET MVC så har vi tidigare fått skapa upp en större mängd controllers med tillhörande vyer, men med ASP.NET MVC 2 så finns möjligheten att skapa dessa areor enklare.

Just ”Area” har blivit ett reserverat ord i routes, så om ni använder det nu så rekommenderar jag att ni ändrar till något annat för att det inte ska krocka om ni uppgraderar. Det är fortfarande bara Preview 2, så det kan dock komma att ändras i senare versioner. Om ni minns hur det var under beta-versionerna av ASP.NET 2.0 så hette t.ex. App_Themes bara Themes, vilket gjorde att många fick problem, och därav prefixet ”App_”. Det finns en möjlighet att det här ändras, men för säkerhets skull så bör ni ändå ändra.

Det som behövs för att ni ska kunna köra exemplet jag kommer att ta upp är ASP.NET MVC 2 Preview 2. I Preview 1 så fanns enbart möjligheten att skapa areor i separata projekt, men nu går det att ha dem i samma som den vanliga sidan.

Vi kommer att ha två areor, Cars och Customers. Vi börjar med att skapa en mapp ”Area” som ligger i roten. I dessa lägger vi sedan till två mappar för Controllers och Views. Det blir alltså en egen uppsättning för varje area. Vi kopierar även web.config-filen från ~/Views till de båda Views-mapparna i areorna för att få med referenserna till rätt namespaces. Till slut så skapar vi en cs-fil vid namn ”Routes.cs” i roten för varje area. Dessa kommer att innehålla routes för de specifika areorna.

Projektet bör se ut så här nu:

1 - Project

Nästa steg blir att skapa upp våra routes i routes.cs-filerna.

För Cars så har jag detta:

using System.Web.Mvc;
 
namespace Areas.Areas.Cars
{
    public class Routes : AreaRegistration
    {
        public override string AreaName
        {
            get { return "cars"; }
        }
 
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "car",
                "cars/{controller}/{action}",
                new { controller = "Home", action = "Index" }
            );
        }
    }
}

Och för Customers:

using System.Web.Mvc;
 
namespace Areas.Areas.Customers
{
    public class Routes : AreaRegistration
    {
        public override string AreaName
        {
            get { return "customers"; }
        }
 
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "customers",
                "customers/{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = "" }
            );
        }
    }
}

Klasserna måste ärva AreaRegistration, och köra en override på AreaName och RegisterArea(). AreaName kommer vi att använda när vi skapar referenser mot den specifika arean, och RegisterArea körs när applikationen startas så att routen skall registreras. Utan dessa så kommer vi inte att kunna komma åt areorna.

Nästa steg är att se till så att RegisterArea-metoden i de olika areorna anropas. Det gör vi genom att lägga till en rad i global.asax.

using System.Web.Mvc;
using System.Web.Routing;
 
namespace Areas
{
 
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            AreaRegistration.RegisterAllAreas();
 
            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );
 
            routes.MapRoute("Kunder", "kunder/{id}", new { id = "" });
 
        }
 
        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

AreaRegistration.RegisterAllAreas() går igenom alla klasser i area-mappen som ärver AreaRegistration och registrerar dem.

Nu har vi fungerande areor som registreras när vi startar sidan första gången. Vi har dock inget innehåll i dessa än.

Härnäst så behöver vi skapa upp modellerna som skall användas. Vi skapar två filer i Models-mappen, Car.cs och Customer.cs. De ser ut som följande:

Car.cs

namespace Areas.Models
{
    public class Car
    {
        public int CarId { get; set; }
        public string Color { get; set; }
        public string Name { get; set; }
    }
}

Customer.cs:

namespace Areas.Models
{
    public class Customer
    {
        public int CustomerId { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

Härnäst behöver vi skapa upp våra controllers, vilket vi gör på exakt samma sätt som tidigare, bara att det sker i våra areor.

CarController.cs:

using System.Collections.Generic;
using System.Web.Mvc;
using Areas.Models;
 
namespace Areas.Areas.Cars.Controllers
{
    public class CarController : Controller
    {
        public ActionResult Index()
        {
            List<Car> cars = new List<Car>() {
                new Car() {
                    CarId = 1,
                    Name = "Volvo",
                    Color = "Röd"
                },
                new Car() {
                    CarId = 2,
                    Name = "Saab",
                    Color = "Gul"
                },
                new Car() {
                    CarId = 3,
                    Name = "Koenigsegg",
                    Color = "Svart"
                }
            };
 
            return View(cars);
        }
    }
}

CustomerController.cs

using System.Collections.Generic;
using System.Web.Mvc;
using Areas.Models;
 
namespace Areas.Areas.Customers.Controllers
{
    public class CustomerController : Controller
    {
        public ActionResult Index()
        {
            List<Customer> customers = new List<Customer>() {
                new Customer() {
                    CustomerId = 1,
                    Name = "Per Persson",
                    Age = 21
                },
                new Customer() {
                    CustomerId = 2,
                    Name = "Nils Nilsson",
                    Age = 53
                },
                new Customer() {
                    CustomerId = 3,
                    Name = "Santa Claus",
                    Age = 1243
                }
            };
 
            return View(customers);
        }
 
    }
}

Vi högerklickar sedan i Index-metoderna och väljer att skapa vyer för dessa. Se till att välja rätt modeller för de olika vyerna!

När vi länkar till en vy som ligger i en area så måste vi lägga till ett värde som specifierar vilken area som vyn tillhör.

I master-sidan så lägger vi till dessa två rader för menyn:

<li><%= Html.ActionLink("Bilar", "Index", "Car", new { area = "cars" }, null)%></li>
<li><%= Html.ActionLink("Kunder", "Index", "Customer", new { area = "customers" }, null)%></li>

Genom att sätta area till namnet som vi angav i areornas routes-filer så genereras länkarna automatiskt så att de går mot dessa.

Vi kan nu klicka på F5 och surfa till sidorna precis som tidigare. Det här är ett enkelt sätt att dela upp större webbplatser på så att vi kan få en bättre struktur än tidigare.

Det finns för tillfället inget sätt att snabbt skapa upp en area på, men förhoppningsvis så kommer ett alternativ för att skapa upp dessa med Routes-filer, web.config och annat från början.

3 Comments

Comments have been disabled for this content.