ASP.NET MVC är ett ramverk som erbjuder ett sätt att utveckla webbplatser som främjar testbarhet, struktur och klar separation av huvudbry. Man får intuitiva url:er och total kontroll över html-kod och css som rendereras. Själva designmönstret Model-View-Controller är ju inget nytt utan har tidigare funnits i webbramverk som t ex Zend, Django, eller Ruby On Rails. Det här handlar alltså om Microsofts implementering för webb av mönstret.
Ramverket utannnonserades av Microsoft i slutet av 2007 och har sedan dess släppts i ett antal förhandstitt-versioner (fem tror jag), en betaversion och nu nyligen en kandidat till den slutgiltiga versionen. Utveckligen har skett i stor samverkan med utvecklarcommunityn och det har varit riktigt roligt att se det växa fram. Det riktiga släppet ska enligt tidigare meddelanden släppas nu under februari månad. Återstår att se ifall de håller den tidsramen, men nu är det hur som helst inte långt kvar.
Det är alltså ett perfekt läge att börja testa med ramverket ifall du inte gjort det tidigare, något jag rekommenderar varmt. Web forms i all ära, när jag har kört MVC ett tag så lockar inte den klassiska modellen längre.
Bra introduktionsartiklar till ASP.NET MVC av Stephen Walter
Stephen Walter skriver för tillfället på boken ASP.NET MVC Framework Unleashed och bjuder på sin blogg på några exempelkapitel från denna. Riktigt bra ifall man vill lära sig runderna i ASP.NET MVC.
I Chapter 1 - An Introduction to ASP.NET MVC ger han en introduktion till vad han anser hur bra mjukvara ska byggas, designmönster, arkitektur och vikten av testdriven utveckling. Han förklarar även hur standardinstallationen av ASP.NET MVC-installationen fungerar.
Vidare med Chapter 2 - Building a Simple ASP.NET MVC Application ber han oss lustigt nog att glömma vad han just sagt om testbarhet och de stora målen med mönstret och visar oss istället hur man bygger en enkel applikation, utan ett enda test. Här får vi dock lära sig hur man skapar projektetet i Visual Studio och bekantar oss med filstruktur coh de allmänna begreppen.
Sen visas i Chapter 3 - Understanding Controllers hur Controllers fungerar, vad för olika typer av resultat de returnerar, hur man kan begränsa dem till att bara acceptera specifika HTTP-attribut och hur man testar dem.
Det i skrivandes stund sista kapitlet som förhandsvisas är Chapter 9 - Understanding Routing och här visas hur man sätter upp sina routes i Global.asax för hur url-stukturen på för sin applikation ska se ut. Han går igenom hur man kan sätta begränsningar på dem och hur man debuggar och testar dem.
En riktigt lärolik samling artiklar alltså och hoppas fler kapitel dyker upp snart. Tänkt bara att detta är temporära kapitel ur boken som kan komma att ändras för att reflektera eventuella sista-minuten-ändringar vi kan komma att få se i den slutgiltiga versionen av ASP.NET MVC.
Köra olika versioner av ramverket samtidigt
Till sist ett litet tips ifall du redan har utvecklat sajter på tidigare versioner och vill testköra den nya RC-versionen utan att oroa dig för att dina tidigare projekt slutar att fungera. Här handlar det om att ta bort MVC-referenserna från GAC efter du installerat den senaste releasen. Man måste in i registret och röja så var försiktig vad du än gör. Jag har följt instruktionerna på min maskin och det gick fint. Mina äldre projekt körs med betaversionens MVC-ddl:er som ligger i respektive projekts Bin-mapp.
Att jag inte ens har provat att skapa ett RC-projekt är en annan femma. Försöker hålla mig eftersom den riktiga versionen kanske släpps typ imorgon...
Har tänkt igenom hur denna blogg kan bli bättre och roligare att läsa och har en del ideér. För att kunna mäta om förändingar är bra eller dåliga så ville jag först sätta upp några mål i Google Analytics, och det har jag sysslat med de senaste dagarna. Tänkte dela med mig av vad jag lärt mig.
Först tänkte jag igenom vad målen med bloggen är och kom fram till att det viktigaste och roligaste är när man får input från sina läsare. Det är på så sätt som bloggen kan utvecklas och växa och därför bestämde jag mig för att sätta upp följande två mål.
Kontaktformulär skickat
Kommentar postad
När man sätter upp mål-urlerna i Google Analytics så har man tre olika alternativ, Exakt matchning, Rubrikmatchning och Matchning av vanliga uttryck. Utan att gå in för mycket på dem så kan jag kontatera att Exakt matchning fungerade bäst för det ja ville göra. Hos Google finns det en bra hjälpsida som förklarar hur de olika alternativen fungerar.
De två målen har jag implementerat lite olika så tänkte förklara här hur jag gjort.
Så satte jag upp mål för Kontaktformuläret
Kontaktformuläret postar tillbaks till sig själv och jag har alltså ännu inte gjort om det till PRG-designmönstret som jag skrev om här om dagen. Eftersom adressen inte ändras var jag tvungen att skicka med den påhittade sida "/contact-form-submitted" som jag angett i mitt första mål.
I ContactControllern (ASP.NET MVC) så skickar jag med parameter i ViewData när användaren har postat meddelandet:
Kommentarsfunktionen har jag nyligen gjort om så den följer PGR-mönstret och här hade jag lite svårare att lägga in spårningskoden på rätt ställe. Provade en del olika grejer där jag bland annat försökte lägga in det på den adress som man postar kommentaren till (bloggurl plus "/add-comment" på slutet). Vet inte exakt varför det inte gick med regulärt uttryck men antar att det beror på att den sidan returnerar en 302-respons (see other adress). Kan vara så att man inte kan tracka såna sidor med Google Analytics.
Sen kom jag på en enklare lösning. La på ett onclick-event på submit-knappen istället där jag anropar pagetrackern och det fungerar nu fint.
Först trodde jag att huvudskriptet där tracken inkluderas var tvungen att ligga ovanför eventet, med det visade det sig att den inte behövde, den har ju redan registrerats när sidan laddas. Google Analytics Tracking API var användbart för felsökning och genom att anropa _getAccount() kunde jag bekräfta att eventet hade kontakt med trackern.
Dags att mäta, förändra och förfina
Så nu är det bara att luta sig tillbaks och börja analyserar hur kommentarer och kontaktmeddelande postas på Code Odyssey. Kom gärna med förslag och ideér hur sidan kan göras bättre för att uppmuntra fler kommentarer och rikare samtal.
Har programmerat om kommentars-funktionen på bloggen och den följer nu designmönstret Post/Redirect/Get (PRG Pattern). Det innebär att när en kommentar postas så görs det till en specifik url som bara accepterar Http-verbet "Post". Sen skickas besökaren tillbaks till inläggets vanliga url med en ankarlänk till den nyligen postade kommentaren tillagd på slutet.
Innan denna förändring så postades kommentaren direkt till samma vy/url som även används till att visa inlägget.
Fördelar med PRG-mönstret
Fördelen med att följa PRG-mönstret är att kommentaren inte dubbelpostas ifall användaren klickar på tillbaka-knappen i sin webbläsare. Nuförtiden så varnar ju dock de flesta moderna webbläsare att en ompostning kommer ske, men det är ofta man inte tänker på att det inte går att backa och det är ett rätt störande meddelande som man slipper med PRG-mönstret.
Sen det Action i Controllern som sätter in kommentarern i databasen och redirectar användaren till rätt vy igen. Det sker lite mer blanda annat har vi ett anti-spam-skydd och kommentarern mailas även till mig (nytt för idag så nu kommer jag vara mer alert på nya kommentarer).
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddComment(int year, int month, int day, string slug)
{
var url = Request.Form["url"];
int postid = Convert.ToInt32(Request.Form["postid"]);
var name = Request.Form["name"];
var body = Request.Form["body"];
var email = Request.Form["mail"];
int addedCommentId = blogService.AddComment(postid, name, body, email, url);
return RedirectToRoute("BlogPostWithAnchor", new { action = "ArchiveBySlug", year = year, month = month, day = day, slug = slug, anchor = "comment-"+addedCommentId });
}
Något som jag måste bli bättre på är att markera oanvända kodstycken som Obsolete. Det innebär alltså att klassen helst inte ska användas längre och har tagit ett steg vidare mot avveckling. Man kan skriva ett meddelande också som kommer upp i kompilern som påminnelse för att man ska ta bort dem.
Ja även fast det är spännande att jobba med nya databas-tekniker som LinqToSQL och Subsonic, så kan det vara bra att kunna lite hederliga DataSet-operationer.
Just nu så hade jag ett problem med Subsonics Paging-funktioner, där en Where-sats inte kom med. Jag fick dubbla poster hur jag än gjorde. Då kom jag på att jag kunde filtrera DataSet:et i efterhand och skrev följande lilla funktion.
Anropar den sedan på följande vis. I detta fallet ville jag ha ut texter på en visst språk, och inte alla språk i databas-tabellen som Subsonic envisade sig med att returnera.
Tänkte visa ett exempel på hur man kan byta ut parametrar i resursfiler. I mitt exempel hämtar jag ut en text för copyright-meddelande och byter ut en parameter {0} med string.format mot aktuellt år.
I resursfilern har jag en nyckel som heter Copyright och lägger in följande sträng.
Hade ett litet problem när jag ville få in en Application-variabel i SelectParameters till en SqlDataSource. Sessions-variabler går ju men ej Application. Se en tutorial för vilka typer av parametrar man kan skicka med som standard.
Googlade runt lite och hittade infomation om något som heter ExpressionBuilder i ramverket som jag aldrig använt tidigare. Med detta kan man skapa egna prefix och koppla det till klasser som tar ut den data man vill åt, och man kan binda värden i kontroller. Så min idé var att skapa en ExpressionBuilder som hämtade ut Application-variabler och det gick väldigt bra.
Här kommer jag gå igenom de steg jag gjorde, det hela handlade om att jag ville åt en egen parameter för vilken @CultureSqlDataSource skulle få som inparameter.
I Global.asx skapar jag parametern baserat på domännamnet. Är det en .se-domän vill jag ha "sv-SE" och för alla andra "en-GB".
protected void Application_BeginRequest(Object sender, EventArgs e) { //Check if domain is swedish Application["CurrentCulture"] = HttpContext.Current.Request.Url.ToString().IndexOf("codeodyssey.se") != -1 ? "sv-SE" : "en-GB"; }
Vi har börjat testa lite smått på några webbsajter att använda ISAPI-modulen som finns installerad hos Binero och det fungerar ganska bra. Vi har till och med fått igång ett första MVC-projekt på .NET 3.5. Riktigt kul med ett webbhotell som är framåt och förstår vilken teknik vi utvecklare vill ha.
Det tog lite tid att lista ut hur man fick igång det eftersom Bineros förklaring av Rewrite 3 inte är så utförlig. De har manualen på deras sajt så där kan man lära sig lite (funkar dock inte med Firefox 3). Helicon Tech som ligger bakom modulen rekommenderas också.
Mest hjälp för att få igång det hade jag av av några trådar på Aspsidan och webForum.
Något att tänka på är att de ändringar man gör i Script Mappings i Bineros kontrollpanel tar ett tag innan de slår igenom. Kommer ihåg den första kvällen då jag kämpade med det in på småtimmarna men hade ingen lycka. Provade mängder av olika konfigurationer och gav sist upp och bara lämnade det. Nästa morgon när jag laddade upp sidan så bara det fungerade!
Så nu ska jag förklara det jag kommit på hittills.
Det första man måste göra är att lägga till en *-mappning enligt följande.
Filetype: * Executable: Aspnet2 is wildcard: false is script engine: false verify that file exists: false
När du ändå är där kan du även lägga till .asax eftersom Binero verkar ha glömt det i standardinställningen. Se bilden för exempel på de två inställningarna längst ner.
Sen är det dags att knåpa ihop en httpd.ini (uppdatering: filen ska ha namnet .htaccess och inget annat) som styr hur ISAPI Rewrite 3 ska uppföra sig. Här under ser ni våran som fungerar fint om man vill ta bort .aspx ändelserna. Jag har dock inte lyckats att exkludera vissa mappar, så om någon kan se vad det är för fel på sista raden som ska blocka mappen "MappSomInteSkaOmskrivas" så uppskattar jag tips. Uppdatering: Denna rad måste ju givetvis ligga överst för att de andra reglerna ska ignoreras. Har nu uppdaterat skriptet som det ska se ut och då funkar det mycket bättre.
# Helicon ISAPI_Rewrite configuration file # Version 3.1.0.34
Oj vilket blogg-uppehåll det varit här, hoppas ni inte saknat oss för mycket. Nu kommer vi köra igång igen och hoppas på att kunna skriva regelbundet här om webbutveckling som vi brukar.
Denna gång bloggar jag från en MacBook Pro, så se fram emot många OS X-relaterade artiklar i framtiden.
Men ni Windows-geeks behöver inte misströsta. Kör Vista i en boot camp installation via VMware Fusion, så det kommer finnas mycket matnyttigt för den plattformen också.
Man kan säga att mitt dataliv har blivit rätt mycket trevligare sen jag kunde pensionera den Dell-burk jag använde innan (och nej Dell har inte hört av sig för att kompensera för den dåliga upplevelsen). Det var inte helt smidigt att ha en dator som stängde av sig själv titt som tätt när den blev överhettat. En del bekanta brukar le så smått när jag berätta om hur jag fick sitta på balkongen med kylklampar under datorn, vid krävande operationer.
Jag har tidigare lovat en utvärdering av hur det fungerar att använda Visual Studio på en Mac via Vista som slavsystem, och kan säga att det går helt okej. I min maskin har jag 2 GB ram och det duger bra åt att köra de båda operativen sida vid sida. Funkar till och med bra att använda det processorintensiva pluginet Resharper som jag blivit så förtjust i.
VMware Fusion som gör det möjligt att köra OS X och Windows (eller andra operativ) samtidigt har många bra inställningar där man bland annat kan ställa in hur mycket ram man vill dedikera till slavsystemet och det går också att simulera två processorer med hjälp av mjukvaran.
Något som är lite svårt i början är att vänja sig vid alla teckenkombinationer. Nu har jag hittat hur jag skriver in det mesta, men saknar fortfarande vänster måsvinge. Så här har jag lite forskning kvar innan jag kodar lika effektivt som på en PC.
Så jag kan gärna rekommendera även gamla Windows-rävar att i alla fall fundera på att switcha till Mac. OS X är ett väldigt skönt operativ som gör de mesta uppgifter till en bättre upplevelse. Mac-masknerna är också väldigt snygga och har väl integrerad hårdvara. Något som jag uppskattar som inte är så intresserad av att mecka med olika drivrutiner fram och tillbaks. På maccen funkar det mesta med en gång, och allt OS X är väldigt lättanvänt.