Introduktion till ASP.NET MVC 2

Inte alls långt efter att ASP.NET MVC släpptes som RTW så kom preview 1 av ASP.NET MVC 2. Precis som olika versioner av .NET så kommer dock inte kunskapen från tidigare versionen att vara bortkastad, utan tvärtom, du kommer att ha stor nytta av det. Om du inte har arbetat med ASP.NET MVC tidigare så rekommenderar jag att du börjar med min introduktionsartikel som du hittar här:

http://weblogs.asp.net/mikaelsoderstrom/archive/2009/04/02/kom-ig-229-ng-med-asp-net-mvc.aspx

Det jag kommer att ta upp i den här artikeln är starkt typade helpers-funktioner och templates. Om du tidigare har använt Dynamic Data (kom med .NET 3.5 SP 1) så kommer du säkert att känna templates-exemplen som jag kommer att gå igenom. Om du inte har kikat på Dynamic Data så kan jag rekommendera att du skapar ett testprojekt där och labbar lite med t.ex. UIHint() för att få bättre förståelse för vad det kan göra.

Värt att tänka på är att artikeln tar upp preview 1 av ASP.NET MVC 2, och för er som var med i de första förhandsvisningarna av ASP.NET MVC 1 vet säkert att det var mycket som förändrades, så när senare previews av ASP.NET MVC 2 släpps så kan mycket i artikeln vara förändrat. Men nog om det, dags att programmera! :-)

Det första som behövs är ASP.NET MVC 2 Preview 1, det hittar ni här:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=d34f9eaa-fcbe-4e20-b2fd-a9a03de7d6dd#tm

När det är installerat så börjar vi med att skapa ett projekt.

1

Lägg märke till att det är .NET 3.5 som används här. Den slutgiltiga versionen kommer att finnas inbyggt i .NET 4.0, men för .NET 3.5 så kommer vi att behöva installera det separat. Om vi kör .NET 3.5 så får vi ingen möjlighet till att köra alla nya funktioner som kommer med .NET 4.0, så vill vi få ut det mesta så rekommenderar jag att du kör med den senare.

När vi nu har vårt projekt så ska vi fortsätta med att skapa en controller som skall användas i exemplet. Projektet har jag givit namnet ”Customers” då det kommer att lista olika kunder. Vi skapar därför en controller vid namn ”CustomersController”. Vi kommer att ha tre olika vyer kopplade till denna, och skapar därmed ActionResults för List, Details och Edit.

3

public ActionResult List()
{
    return View(GetCustomers());
}
 
//
// GET: /Customers/Details/5
 
public ActionResult Details(int id)
{
    Customer customer = GetCustomers().Where(c => c.CustomerId == id).SingleOrDefault();
 
    return View(customer);
}
 
//
// GET: /Customers/Edit/5
 
public ActionResult Edit(int id)
{
    Customer customer = GetCustomers().Where(c => c.CustomerId == id).SingleOrDefault();
 
    return View(customer);
}

För att slippa hämta data från en databas nu så kör vi en liten fuling och lägger till den här metoden i samma klass:

public List<Customer> GetCustomers()
{
    List<Customer> customers = new List<Customer>();
 
    customers.Add(new Customer()
    {
        CustomerId = 1,
        FirstName = "Sven",
        LastName = "Svensson",
        Birthday = new DateTime(1900, 01, 01)
    });
 
    customers.Add(new Customer()
    {
        CustomerId = 2,
        FirstName = "Nils",
        LastName = "Nilsson",
        Birthday = new DateTime(1948, 10, 22)
    });
 
    customers.Add(new Customer()
    {
        CustomerId = 3,
        FirstName = "Petter",
        LastName = "Pettersson",
        Birthday = new DateTime(1940, 05, 12)
    });
 
    return customers;
}

För att det skall fungera så måste vi även skapa en klass i Models-mappen vid namn Customer.cs och som är modellen vi kommer att använda oss utav. Det är en enkel klass med olika properties för CustomerId, FirstName, LastName och Birthday.

public class Customer
{
    public int CustomerId { get; set; }
 
    public string FirstName { get; set; }
 
    public string LastName { get; set; }
 
    public DateTime Birthday { get; set; }
}

Nästa steg är att skapa vyerna för kunderna. Vi skapar en mapp i Views-mappen vid namn Customers. Där skapar vi tre vyer som använder Customer-klassen. Det bör se ut i stil med det här:

2

För att se listningen i menyn så lägger vi slutligen till det här i master-sidan:

<li><%= Html.ActionLink("Customers", "List", "Customers")%></li>

Om vi kör sidan nu så kan vi se att vi kan se sidor för listning, detaljer och ändringar.

Som det ser ut nu så är det inget som skiljer sig från ASP.NET MVC 1, så det vi gör nu är att öppna upp Details.aspx. Här kommer vi att använda oss utav de hårt typade metoderna LabelFor() och EditorFor(). Dessa gör det möjligt att enkelt använda oss utav templates och data annotations för att modifiera utseendet.

Istället för en label för fältnamnet så kommer vi att använda Html.LabelFor():

<%= Html.LabelFor(c => c.CustomerId) %>

Och för textrutorna så kommer vi att använda Html.EditorFor():

<%= Html.EditorFor(c => c.CustomerId) %>

Ser vi på sidan nu så ser vi ingen skillnad. Det vi vill göra är att istället för CustomerId skriva ut Kund-ID på alla ställen där vi använder LabelFor() för det fältet.

Det vi gör nu är att vi öppnar upp Customer.cs i Models-mappen. Här ska vi använda DisplayName-attributet för att ändra vilken text som visas.

[DisplayName("Kund-ID")]
public int CustomerId { get; set; }

Det som händer nu är att vi istället för ”CustomerId” faktiskt får upp ”Kund-ID” på sidan! Det här gör att vi på ett väldigt enkelt sätt kan anpassa utseendet för de olika fälten i modellen. Värt att notera är dock att vi inte kan använda lokalisering i det här attributet, utan då få vi istället lösa det på ett annat sätt.

Nästa funktion som vi ska använda är något annat som användes flitigt med Dynamic Data, nämligen UIHint-attributet. Skillnaden från DisplayName är att det kan användas för att skapa anpassade kontroller för olika fält. Flera fält kan använda sig utav samma UIHint-kontroll.

Som exempel så kommer jag att skapa en MVC View User Control vid namn ”CapitalString.ascx”. Det kontrollen kommer att göra är att köra .ToUpper() på alla strängar som använder denna. Vi lägger denna i en ny mapp under Shared som vi kallar för DisplayTemplates (går även att skapa EditTemplates om man vill göra om fälten som används i Edit-läget).

Utseendet för denna ser ut som följande:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%= Model.ToUpper() %>

Kontrollen förväntar sig här att det som tas emot är av typen string, vilket vi anger i Inherits-attributet. Model i det här fallet är det värdet (eller den mer avancerade typen om vi har angett en sådan).

För att applicera denna på ett fält (i det här fallet FirstName”) så lägger vi till UIHint-attributet med namnet på kontrollen som parameter på FirstName-propertyn:

[UIHint("CapitalString")]
public string FirstName { get; set; }

Om vi nu går till en Details-sida så kommer vi se att det står till exempel SVEN istället för Sven.

Vi kan även skapa templates som gäller för alla instanser av den aktuella typen. Det vi ska göra är att byta ut alla DateTime-fält mot antalet år sedan det aktuella datumet så kan vi skapa en kontroll med namnet DateTime.ascx och lägga i DisplayTemplates-mappen. Då DateTime är en value type och vi bara kan skicka med en reference type till ViewUserControl<T> så måste vi använda den ickegeneriska varianten och sedan typa om modellen till en DateTime.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= DateTime.Now.AddYears(-((DateTime)Model).Year).Year%>

Det är inte ett helt klockrent sätt att räkna år på, men får duga för det aktuella syftet.

Om vi nu går till en Details-sida så ser vi istället för datumet antal år som har gått sedan det.

Det går med dessa funktioner att skapa delar av sidan som enkelt kan appliceras på ett flertal (eller alla som i DateTime-exemplet) ställen på sidan genom att helt enkelt ändra i en enda fil.

Det här kan vara väldigt användbart när man skall hantera mycket data på sidan och behöver lista samma sak på flera ställen. På det här viset så slipper man ändra på alla olika ställen, utan anger bara med UIHint vilken template som skall användas.

4 Comments

Comments have been disabled for this content.