Framtiden för ASP.NET MVC

Jag har tidigare nämnt att det som finns i ASP.NET MVC 2 Preview 2 (och Preview 1 förstås) är något som är långt ifrån färdigt, och mycket väl kan fungera helt annorlunda när det väl är släppt. Ser man på ASP.NET MVC 1 så var det enorm skillnad på de första preview-versionerna jämfört med den färdiga produkten.

Men finns det något roligare än att labba med preview-versionerna av ASP.NET MVC? Japp! Man kan även labba med ASP.NET MVC Futures. :-)

ASP.NET MVC Futures är ett paket med funktioner som inte har kommit till det stadiet där det kan användas i preview-versionerna. Det beror på att de mest används för att testa nya funktioner, som eventuellt kan hamna i en preview och därefter möjligtvis kan hamna i den färdiga produkten. Det har även släppts några ASP.NET Futures för vanliga ASP.NET, där vissa funktioner kommer med, andra inte.

Innan jag går vidare så rekommenderar jag att du laddar ned ASP.NET MVC Futures, vilket du hittar här:

http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33836

Det ni behöver är både ASP.NET MVC 2 Preview 2, och ASP.NET MVC Futures Assembly for Preview 2.

Sätt upp projektet

När det är nedladdat så skapa ett ASP.NET MVC 2-projekt. Här lägger vi till en klass i models-mappen som ser ut på detta vis:

public class Customer
{
    [DisplayName("Kund-ID")]
    public int CustomerId { get; set; }
 
    [Required(ErrorMessage = "Du måste ange ett förnamn!")]
    public string FirstName { get; set; }
 
    [Required(ErrorMessage = "Du måste ange ett förnamn!")]
    public string LastName { get; set; }
 
    [Required(ErrorMessage="Du måste ange ett födelsedatum")]
    public DateTime Birthday { get; set; }
}

Vi kommer även att skapa en CustomerController, där vi lägger till den här metoden på slutet för att få lite dummy-data:

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;
}

Vi ser även till att vi får vår lista till Index-metoden:

return View(GetCustomers());

Skapa sedan en Index-view som är hårt typad till Customer och som ska lista kunder.

För att få en länk till den här sidan så lägger vi även till det här i master-sidan:

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

Det vi har nu är en helt vanlig ASP.NET MVC 2-sida med möjlighet att lista kunder. Om något verkar oklart så rekommenderar jag att du läser mina introduktionsartiklar till ASP.NET MVC innan du fortsätter.

Webbkontroller för ASP.NET MVC

Japp, det är sant. Webbkontroller kommer (eventuellt) till ASP.NET MVC, precis som de fanns för ASP.NET Web Forms. Min första tanke var något i stil med ”WTF!? OMFG!!!”, men efter att ha testat lite så verkar det inte alltför dumt då det gör det enklare att introducera ASP.NET Web Forms-utvecklare till ASP.NET MVC.

För att kunna använda webbkontrollerna så börjar vi med att lägga till den här raden i web.config under configuration/system.web/pages/controls:

<add tagPrefix="mvc" namespace="Microsoft.Web.Mvc.Controls" assembly="Microsoft.Web.Mvc" />

Det här gör att vi slipper skapa referenser till assemblyn på varje sida där vi använder kontrollerna, vilket gör aspx-filerna lite renare. Anledningen till att jag har satt ”mvc” som prefix är för att det annars kan krocka med den vanliga webbkontrollerna.

Vi kan även lägga till kontrollerna i toolboxen i Visual Studio. Det gör vi genom att högerklicka i toolboxen, välja ”Choose Items…” och sedan bläddra fram till Microsoft.Web.Mvc. När vi väljer den assemblyn så får vi automatiskt alla kontroller som finns i den.

Vi har nu det här i vår toolbox:

1 - Toolbox

Det finns alltså kontroller för de funktioner som vi använder oftast i vår applikation. Jag kommer att gå igenom dessa en för en, för att visa hur det fungerar.

Webbkontroller

ActionLink

Den första kontrollen vi har är en ActionLink, vilken gör exakt vad det låter som. För att använda den på vår sida så öppnar vi först upp master-sidan. Sedan byter vi ut vår customer-länk som nu ser ut så här:

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

Mot:

<li><mvc:ActionLink runat="server" ActionName="Index" ControllerName="Customer" Text="Customers" /></li>

Det är alltså en webbkontroll som använder properties för att ange action, controller och texten som skall synas.

Något som är väldigt positivt här är att det inte renderas någon hemsk HTML i stil med Web Forms, utan det som kommer är ett vanligt a-element precis som för Html.ActionLink(). Kontrollen kan ses som en Html.ActionLink(), men utan kodblocken runt.

DropDownList

DropDownList-kontrollen returnerar en enkel select-lista på sidan. Då ASP.NET MVC inte har stöd för PostBacks så finns ingen möjlighet att använda AutoPostBack på kontrollen, utan sådant får man sköta med egna JavaScript om man så önskar.

För att använda kontrollen så lägger vi först in kontrollen på index-sidan:

<mvc:DropDownList runat="server" Name="customers" />

För att kunna fylla den med data så måste vi använda ViewData[”customers”] och fylla den med en IEnumerable<SelectListItem>. Då fylls vår DropDownList med datan som finns i ViewData-objektet.

Koden vi använder i controllern för att fylla listan med namnen på alla personer är:

List<SelectListItem> customers = new List<SelectListItem>();
 
foreach (Customer customer in GetCustomers())
{
    customers.Add(new SelectListItem()
    {
        Text = customer.FirstName + " " + customer.LastName
    });
}
 
ViewData["customers"] = customers;

När vi sedan kör sidan så får vi upp en enkel lista med alla namn:

2 - Dropdownlist

Hidden

Det händer ofta att man vill ha med dolda input-fält på klienten som sedan skall följa med när man postar.

När man använder kontrollen så ser det ut så här:

<mvc:Hidden runat="server" Format="hemlis" Name="hiddenfield" />

Det renderas så här:

<input name="hiddenfield" type="hidden" value="hemlis" />

Format är alltså värdet vi vill skicka med och Name just namnet som sedan används när man ska plocka fram värdet vid en postning.

Label

En ganska användbar kontroll är Label-kontrollen. Det som renderas är ren text, ungefär som Literal-kontrollen för Web Forms. Den har dock vissa funktioner för att kapa texten efter en viss längd, vilket kan vara användbart när man t.ex. skriver ut kortfattade nyheter på startsidan och sedan vill länka till den fullständiga nyheten.

När man använder den med alla dess properties så ser den ut så här:

<mvc:Label
    runat="server"
    Name="lbl"
    EncodeType="Html"
    Format="En label med en massa text. Den kapas efter 15 tecken."
    TruncateLength="15"
    TruncateText="..."
    Visible="true"
    />

Name måste anges trots att den inte används.

EncodeType kan sättas till None, Html och HtmlAttribute, där den Html och HtmlAttribute kör HtmlEncode på texten.

Format är själva texten som skall skrivas ut.

TruncateLength avgör hur många tecken som ska visas.

TruncateText visar vilken text som skall visas efter att den inmatade texten har klippts. HtmlEncode körs aldrig på denna.

Visible är en boolean och kan sättas till false om man inte vill att texten skall visas.

Password

Password-kontrollen renderar ett vanligt lösenordsfält.

Den används på det här sättet:

<mvc:Password Name="pwd" runat="server" />

Det som matas in blir automatiskt dolt för användaren.

TextBox

TextBox-kontrollen renderar en vanlig textruta på sidan.

<mvc:TextBox
    runat="server"
    Format="Text..."
    Name="textruta"
    Visible="true"
    />

Format innehåller standardvärdet för kontrollen och visible avgör om den skall visas eller ej.

Repeater

En av de mest intressanta kontrollerna är repeater-kontrollen. När man arbetar med ASP.NET MVC och har foreach-loopar i kodblock direkt i koden så kan det lätt bli rörigt. Det kan Repeater-kontrollen lösa snyggt.

Den kan användas så här:

<mvc:Repeater runat="server" Name="rptcustomers">
    <EmptyDataTemplate>
    <li>Ingen data...</li>
    </EmptyDataTemplate>
    <ItemTemplate>
    <li>
        <%#Eval("FirstName") %>
    </li>
    </ItemTemplate>
</mvc:Repeater>

Om vi kör sidan nu så ser vi bara texten ”Ingen data…”, vilket beror på att vi ännu inte har skickat med någon data till kontrollen.

För att fylla repeater-kontrollen med data så lägger vi till det här i controllern:

ViewData["rptcustomers"] = GetCustomers();

Det som sker nu är att vi har bundit vår List<Customer> till Repeater-kontrollen, vilket gör att vi kommer åt alla element genom Eval(”property”).

Gör dina vyer Rest-baserade

Något som är riktigt häftigt och som följer med i ASP.NET MVC 2 Futures är möjligheten att använda sina vyer för rest-baserade anrop. Vi kan på ett väldigt enkelt sätt göra det möjligt att returnera XML eller Json istället för de vanliga HTML-baserade vyerna.

För att göra det här möjligt så lägger vi till de här raderna i Application_Start() i global.asax:

ResourceControllerFactory factory = new ResourceControllerFactory();
ModelBinders.Binders.DefaultBinder = new ResourceModelBinder();
 
ControllerBuilder.Current.SetControllerFactory(factory);

När vi sedan vill göra det möjligt att använda Rest för en vy så lägger vi till WebApiEnabled-attributet på de metoder i våra controllers där vi vill ha det.

Exempel:

[WebApiEnabled]
public ActionResult Index()

Om vi nu surfar till /Customer?format=xml så får vi det här:

3 - XML

Vi kan även ange format=json för att få det som Json, vilket underlättar om vi kör med Ajax för att rendera data.

Det här gör det riktigt smidigt att kunna använda Rest för att kunna hantera datan på sidan.

Om vi har tur så kommer det här till ASP.NET MVC 2!

ViewState i ASP.NET MVC? WTF?

Något som gör att många föredrar ASP.NET MVC framför ASP.NET Web Forms är just det att man inte har någon ViewState. I ASP.NET MVC Futures så kan vi dock hitta detta. Det är inte riktigt samma sak som i Web Forms, utan vi får istället möjlighet att påverka den helt, och vi behöver inte använda den om vi inte vill.

För att testa detta så skapar vi en Edit-sida för våra customers.

Under raden med ”using (Html.BeginForm())” så lägger vi till det här:

<%= Html.Serialize("customer", Model) %>

När vi sedan kollar i den renderade HTML-koden så ser vi det här:

<input name="customer" type="hidden" value="/wEykAIAAQAAAP////8BAAAAAAAAAAwCAAAAPkZ1dHVyZXMsIFZlcnNpb249MS4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBQEAAAAXRnV0dXJlcy5Nb2RlbHMuQ3VzdG9tZXIEAAAAGzxDdXN0b21lcklkPmtfX0JhY2tpbmdGaWVsZBo8Rmlyc3ROYW1lPmtfX0JhY2tpbmdGaWVsZBk8TGFzdE5hbWU+a19fQmFja2luZ0ZpZWxkGTxCaXJ0aGRheT5rX19CYWNraW5nRmllbGQAAQEACA0CAAAAAQAAAAYDAAAABFN2ZW4GBAAAAAhTdmVuc3NvbgBAVyBTBVEICw==" />

Det som lagras är den aktuella typen som modellen använder. Det kan sedan användas när man postar formuläret, vilket gör att vi kan skippa vissa fält i formuläret och bara ta med det vi vill.

Det finns även en tredje parameter till Serialize-metoden som vi kan använda om vi vill, nämligen en av typen SerializationMode. Det är en enum med fyra fält, Encrypted, EncryptedAndSigned, PlainText och Signed. Standard är PlainText, vilket returnerar en Base64-kodad sträng.

Det här är något som finns med, men som absolut inte behöver användas. Vi kan lika väl dölja denna.

När vi tar emot postningen i en controller så måste vi sedan ha med en parameter av typen Customer och som har Deserialize-attributet. Då får vi automatiskt med alla ordinare värden, även om vi bara har ett fält för namnet i formuläret.

Det är upp till var och en om man vill använda serialisering eller inte. Fördelen är att man inte behöver fält för värden man inte bryr sig om, nackdelen är att html-koden blir fulare.

Det finns även en del annat intressant i ASP.NET MVC Futures, men det här är de delar som jag ser som mest intressanta i nuläget.

2 Comments

Comments have been disabled for this content.