ASP.NET MVC Broncode Refresh Preview

Onlangs openden we een nieuw ASP.NET CodePlex Project dat we zullen gebruiken om previews aan te bieden (met bewerkbare broncode) voor verschillende verwachte ASP.NET toepassingen en releases.Vorige maand hebben we het gebruikt om de eerste drop van ASP.NET MVC broncode te publiceren.

Die eerste drop bevatte de bron voor de ASP.NET MVC preview 2 release die we hebben geintroduceerd op MIX, samen met de Visual Studio project bestanden om het zelf te patchen en bouwenEnkele uren terug hebben we een refresh gepubliceerd van de ASP.NET MVC broncode op de website. 

Deze bron refresh is geen officiële nieuwe ASP.NET MVC preview release. Het is een tijdelijke drop dat een blik gunt op de huidige staat van de bron boomstructuur. We zullen de officiële “ASP.NET MVC preview 3” release binnen een paar weken lanceren, nadat we wat meer werk hebben verricht (meer functies en kneepjes dan de bestaande, betere VS tools integratie, VS express editie ondersteuning, documentatie, enz…). Als je zelf iemand bent die liever een eenvoudige installatie heeft van ASP.NET MVC dat uitgebracht wordt met documentatie en volledige tool ondersteuning, dan zal je waarschijnlijk wel willen wachten op de officiële preview release. Als je integendeel graag de kans krijgt om een vroege ‘preview van de preview” te zien en graag de mogelijkheid krijgt om bepaalde delen al uit te testen en feedback te geven, dan is de bron refresh van vandaag zeker interessant voor jou.  

 

Verbeteringen met de ASP.NET MVC Bron Refresh

De update van deze week (die je hier kan downloaden) bevat een aantal verbeteringen op ASP.NET MVC. Een paar voorbeelden:

  • We posten niet alleen de broncode voor het ASP.NET MVC framework, maar ook de broncode voor de unit tests die we gebruiken om het te testen. Deze tests zijn geïmplementeerd met MSTest en het open source Moq mocking framework.  Er is ook een VS 2008 project bestand voor de unit tests in opgenomen. Zo is het eenvoudig te bouwen en lokaal te runnen in je VS 2008 IDE;
  • Er is beduidend eenvoudigere ondersteuning om Controller classes te testen. Je kunt nu gewone Controller scenario’s zonder andere objecten hoeven te raken (meer details over de werkwijze hieronder);
  • Er zijn verschillende leuke functies en verbeteringen voor de gebruiksvriendelijkheid toegevoegd (meer details hieronder).

 

Een nieuw ASP.NET MVC Project creëren

Je kunt je eigen versie van de ASP.NET MVC assemblies bouwen door de MVC bron te downloaden en lokaal te compileren. Je kunt ook een VS template pakket downloaden voor een voorgebouwde versie van die bron samen met een Visual Studio project template die je kan gebruiken om snel een nieuw ASP.NET MVC project te bouwen dat gebruik maakt van de nieuwste bits.

Nadat je de ASP.NET MVC bron hebt geïnstalleerd, moet je vernieuwen. Dan zal VSI template een nieuwe ‘ASP.NET MVC applicatie’ project template doen verschijnen onder “My Templates” sectie van je ‘New Project’ dialoog:

 

 

Deze nieuwe "My Templates" versie van de MVC project template bestaat parallel met de vorige ASP.NET MVC Preview 2 release (die je erboven kan zien in de main project templates sectie van het dialoog). Hierdoor kun je veilig nieuwe projecten creëren en zowel de laatste bronversie als de laatste officiele preview gebruiken op dezelfde computer.

Als je een project creëert met deze vernieuwde ASP.NET MVC project template, dan zal je standaard een project krijgen die er als volgt uitziet:

 

 

 

Deze nieuwe project oplossing bevat een controller (“HomeController”) onder de “\Controllers” directory en twee View templates (“About” en “Index”) onder de “\Views\Home” sub-directory.Beide view templates zijn gebaseerd op een gewone master pagina voor de website (“Site master”), waarvan alle stijlen gedefinieerd worden in een “Site.css” bestand onder de “\Content” directory.

Als je de applicatie runt, dan zal de ingebouwde webserver automatisch opstarten en zal je de “Home” content zien van de website:

 

 

 

Als je klikt op de “About Us” tab, dan zal je de “About” content te zien krijgen:

 

 

De “HomeController” klasse in het project is verantwoordelijk voor de URL’s bovenaan en heeft twee action methodes zoals hieronder:

 

 

 

De standaard “Site master” template zoekt een “Title” waarde in de ViewData collectie en gebruikt die om het <title> element van de HTML pagina te genereren.  De standaard “Index” view template zoekt naar een “Message” waarde om die te gebruiken om de welkomstboodschap op de homepage te gereneren. Je kunt deze bestanden natuurlijk bewerken en personaliseren zoals je dat zelf wilt.

 

Controller wijzigingen in deze ASP.NET MVC Drop

 

Als je de bovenstaande code aandachtig hebt gelezen dan zal je misschien enkele wijzigingen opgemerkt hebben met betrekking tot hoe Controller klassen standaard geimplementeerd zijn in deze nieuwe ASP.NET MVC bron refresh drop. Met de ASP.NET MVC Preview 2 release echter, zouden de bovenstaande HomeController action methodes geïmplementeerd zijn zoals hieronder:

 

Het MVC functie team experimenteert op dit moment met enkele ideëen in de drop van deze week en ze proberen enkele ideëen uit:
  1. De Action methodes op Controllers retourneren nu standard een "ActionResult" object (in de plaats van void).  Dit ActionResult object duidt het resultaat van een andere action aan (een view om te genereren, een URL waarnaar te redirecten, een andere actie/route om uit te voeren, enz…).
  2. De RenderView(), RedirectToAction(), en Redirect() hulpmethodes op de Controller base class retourneren nu typed ActionResult objecten (die je verder kan manipuleren of kan laten retourneren van action methods).
  3. De RenderView() hulpmethode kan nu aangesproken worden zonder expliciet de naam van de te genereren view template erin te plaatsen. Als je de templatenaam weglaat, dan zal de Renderview() methode standaard de naam van de actie methode gebruiken als de naam van de te genereren view template. Dus de “RenderView()” zonder parameters in de “About()” actie method is nu hetzelfde als expliciet “RenderView(‘About’)” schrijven.

Het is redelijk gemakkelijk om bestaande Controller classes te updaten die gebouwd zijn met de Preview 2 om dit nieuwe patroon te gebruiken (gewoon void to ActionResult wijzigen en een return statement toevoegen vóór elke RenderView of RedirectToAction helper methode calls).

 

ActionResult Objecten uit Action Methodes

 

Waarom Controller action methodes wijzigen om standard Action Result objecten te retourneren in de plaats van een void methode ? Tal van andere populaire Web-MVC frameworks doen dit  (Django, Tapestry en andere), en wij vonden voor ASP.NET MVC dat het een paar voordelen opbracht :
  1. Het maakt de unit testing support voor Controllers beter en gemakkelijker. Je hoeft niet langer methodes te imiteren in het Response object of in de ViewEngine objecten om het reageergedrag (behaviors) van de action methodes te kunnen unit testen.
  2. Het maakt de Controller logic flow intenties iets duidelijker en explicieter in scenario’s waarin er 2 verschillende resultaten mogelijk zijn, afhankelijk van bepaalde voorwaarden (bijvoorbeeld : zend door (redirect) als voorwaarde A waar is, anderzijds genereer een ViewTemplate als het onwaar is). Dit kan minder belangrijke controller action methodes gemakkelijker leesbaar en volgbaar maken.
  3. Het creëert een goed opgebouwd script waar een FilterActionAttribute het resultaat van een action method kan nemen en wijzigen nog voordat het uitgevoerd wordt. Bijvoorbeeld : een “Browse” action op een ProductCatalog controller kan een RenderActionResult retourneren dat aangeeft dat het zal gegenereerd worden als ListView van de producten. Een FilterActionAttribute die declaratief op de controller class geplaatst was, zou dan de specifieke “List” view template kunnen personaliseren dat gegenereerd werd als een list-html.aspx ofals  een list-xml.aspx, afhankelijk van het verkozen MIME type van de client. Meervoudige FilterActionAttributes  kunnen ook samengebracht worden in een keten om de resultaten van de een naar de ander te laten vloeien.
  4. Het biedt een goed uitbreidingsmechanisme zodat mensen (onszelf inbegrepen) bijkomende functies kunnen toevoegen in de toekomst. Nieuwe ActionResult types kunnen gemakkelijk gecreëerd worden door van de ActionResult base class een subclass te maken en de “ExecuteResult” methode te overschrijven (override). Het zou gemakkelijk zijn om een “RenderFile()3 helper methode te creëren zodat een ontwikkelaar die bijvoorbeeld een action schrijft een nieuw “FileActionResult” object zou kunnen laten retourneren.
  5. Het zal in de toekomst enkele mooie Asynchrone uitvoerscenario’s mogelijk maken. Action methodes zullen een AsyncActionResult object kunnen retourneren dat aanduidt dat ze wachten op een netwerkactie en dat ze aangeeft dat ASP.NET ondertussen via een worker thread een ander verzoek kan uitvoeren totdat het netwerk de actie heeft vervolledigd. Hierdoor zullen ontwikkelaars kunnen vermijden dat threads worden geblokkeerd op een server.Ze zullen efficiënte en opbouwbare code kunnen ondersteunen.
Een van de doelstellingen van deze interim preview is de mensen een kans geven om wat te oefenen met deze nieuwe benadering en echte applicaties te bouwen en om gewoon bij te leren.We zullen ook een ander Controller base class voorbeeld posten dat je kunt gebruiken als je nog de vorige “void” action benadering verkiest. We hebben met opzet deze andere Controller base class niet opgenomen in deze bron refresh drop, want we willen de mensen aanmoedigen om de “ActionResult” benadering uit te proberen, zodat ze ons hun feedback kunnen bezorgen.

 

Hoe Controller Action Methods Unit Testen

 

Hierboven heb ik vermeld dat met de nieuwe ActionResult benadering unit tests van controllers veel gemakkelijker verlopen (het is ook niet meer nodig om gewone scenario’s te imiteren).We zullen even een voorbeeld hiervan bekijken:Bekijk even de eenvoudige NumberController class hieronder:

 

 

Deze Controller class heeft een “IsEventNumber” actie methode dat een nummer neemt als een URL argument. De “IsEventNumber’ actie methode controleert eerst of het nummer negatief is. In dat geval wordt de gebruiker naar een error pagina geleid. Als het nummer positief is, dan bepaalt de “IsEventNumber” of het nummer even of oneven is. Daarna genereert het een view template die een gepaste boodschap toont:

 

 

 

Het is redelijk gemakkelijk om unit tests schrijven voor onze “IsEventNumber” action method dankzij onze nieuwe ActionResult benadering. Hieronder staat een voorbeeld van een unit test dat nagaat of de juiste http redirect gebeurt als een negatief nummer wordt gegeven (bijvoorbeeld:/Number/IsEventNumber/-1):

 

 

 

Merk op dat we geen enkel object hebben moeten imiteren om onze action methode te testen. We hebben gewoon de NumberController class geconcretiseerd en we hebben de action methode direct aangesproken (met een negatief nummer). Ook hebben we de return waarde toegekend aan een lokale “result” variabele. Ik heb de C# “as type” syntax gebruikt hierboven om de “result” variabele als een sterk “HttpRedirectResult” type te modelleren.

Wat zo leuk is aan het C# “as” sleutelwoord is dat het een waarde als null zal toekennen in de plaats van een uitzondering weer te geven als de cast mislukt (vb, als de action methode een RenderViewResult retourneert). Dit betekent dat ik gemakkelijk een assertion controle kan toevoegen aan mijn test om te controleren of mijn resultaat niet null is om te kunnen controleren date en Http redirect is gedaan. Dan kan ik een tweede assertion controle toevoegen om te controleren dat de correcte redirect URL was gespecificeerd.

De tests voor scenario’s waarin ook niet-nul nummers zijn ingevoegd zijn ook gemakkelijk. Om dit te doen zullen we twee test methodes creëren: een om even nummers te testen en een om oneven nummers te testen. In beide tests zullen we vaststellen of een RenderViewResult was geretourneerd, en dan zullen we nagaan of de correcte “Message” string ingevoegd was in de ViewData die gerelateerd is aan de view:  

 

 

Daarna kunnen we klikken met de rechtermuisknop op op onze NumberControllerTest class in VS 2008 en het “Run Tests” menu item selecteren:

 

 

Hierdoor zal onze three unit tests in-memory uitgevoerd worden (geen webserver vereist) en zal er gerapporteerd worden of onze NumberController.IsEventnumber() action methode het juiste gedrag vertoont:

 

 

Noot: in de bron drop van deze week moet je nog steeds de imitatiemethode gebruiken om de TempData eigenschap te testen op Controllers. Volgens ons plan is het niet meer nodig is om dit te testen met de ASP.NET MVC Preview 3 drop binnen een paar weken.

 

MapRoute Helper Methode

 

URL routing rules in ASP.NET MVC applicaties worden normaal gedeclareerd in de “RegisterRoutes” methode van de Global.aspx class.Met ASP.NET MVC Previews 1 and 2 werden routes toegevoegd aan de route collectie door een Route object onmiddellijk te concretiseren, door het te schrijven naar een MvcRouteHandler class. Daarna moeten we de juiste eigenschappen toekennen en de route regels declareren:

 

 

De bovenstaande code zal verder voorwaarts werken. Je kan echter ook gebruik maken van de nieuwe “MapRoute” helper methode die een veel eenvoudigere syntax biedt om hetzelfde te bereiken. Hieronder zie je een conventionele URL route die standaard geconfigureerd is als je een nieuw ASP.NET MVC project creëert (en die de bovenstaande code vervangt):

 

 

 

De MapRoute() helper methode is overgeladen en gebruikt twee, drie of vier parameters (route naam, URL syntax, URL parameter default, and URL parameter regular expression constraints).  Je kan de MapRoute() zoveel keer aanspreken als je wilt om meerdere routes bij naam te registeren in het systeem. Bijvoorbeeld, naast de standaard conventie regel, zouden we een “Product-Browse” genaamde route kunnen toevoegen zoals hieronder:

 

We kunnen dan expliciet naar deze “Products-Browse” regel refereren in onze Controllers en Views als we een URL ernaar willen genereren. Bijvoorbeeld, we zouden de Html.RouteLink view helper kunnen gebruiken om aan te duiden dat we willen linken naar onze “Products-Browse” route en dat we het een “Food” categorie parameter willen geven in onze view template zoals hieronder:

 

 

 

Deze view helper zou dan toegang krijgen tot het routing system en zou een geschikte html hyperlink url genereren zoals hieronder (merk op hoe het automatisch de parameters van de categorie parameters verwisselde in de URL met de route regel):

 

 

Noot: met de source drop van deze week moet je de controller en de action parameters inpassen (naast de Categorie parameter) in de Html.RouteLink() helper om de correcte route url te kunnen genereren. In de ASP.NET MVCC Preview 3 drop binnen enkele weken zal dit niet nodig zijn. Je zal de Html.RouteLink kunnen gebruiken zoals ik hierboven heb beschreven.

 

Andere URL Route Mapping Functies

 

De MVC source drop van deze week ondersteunt ook een aantal nieuwe URL route mapping functies. Je kan nu "-", ".", ";" of andere karakters gebruiken als deel van je route regels.Bijvoorbeeld, als je een "-" scheider gebruikt, dank an je nu de taal en lokale warden parsen van al je URL’s met een regel zoals hieronder:

 

 

 

Dit zou gepaste "language", "locale", and "category" parameters doorgeven aan de  ProductsController.Browse action methode als het aangeroepen wordt:

 

URL Route Rule Example URL Parameters Passed to Action method
{language}-{locale}/products/browse/{category} /en-us/products/browse/food language=en, locale=us, category=food
  /en-uk/products/browse/food language=en, locale=uk, category=food

 

Of je kunt de"." bestandsextensie aan het einde van een URL gebruiken om te bepalen of het resultaat in XML of HTML formaat moet worden gegenereerd:

 

 

 

Dit zou zowel de "category" en een "format" parameters doorgeven aan de ProductsController.Browse action methode wanneer aangeroepen:

 

URL Route Rule Example URL Parameters Passed to Action method
products/browse/{category}.{format} /products/browse/food.xml category=food, format=xml
  /products/browse/food.html category=food, format=html

 

ASP.NET MVC Preview 2 introduceerde wildcard route regels. Bijvoorbeeld, je kunt in een regel aanduiden om alle overblijvende URI content op een genoemde parameter door te geven aan een action methode:

 

 

 

Dit zou een  "contentUrl" parameter doorgeven aan de WikiController.DisplayPage action methode wanneer aangeroepen:

 

URL Route Rule Example URL Parameters Passed to Action method
Wiki/Pages/{*contentUrl} /Wiki/Pages/People/Scott contentUrl="People/Scott"
  /Wiki/Pages/Countries/UK contentUrl="Countries/UK"

 

Deze wildcard routes blijven prima werken met de preview van deze week. Ze zijn ook heel nuttig om te bekijken als je een blog, wiki cms of ander contentgebaseerd system aan het bouwen bent. Merk ook op dat we naast dit nieuw route systeem voor ASP.NET MVC scenario’s nu ook hetzelfde route systeem gebruiken in ASP ASP.NET Dynamic Data (dat gebruik maakt van ASP.NET Web Formulieren).

 

Samenvatting

 

Hopelijk bood de bovenstaande post een snelle update over enkele van de nieuwe functies en vernieuwingen van de ASP.NET MVC bron update drop. 

Je kunt het hier downloaden als je het onmiddellijk wil gebruiken. Je kunt ook nog enkele weken wachten op de officiële ASP.NET MVC Preview 3 drop – die nog meer functies zal bevatten(en de feedback die de mensen zullen hebben gegeven op de drop van deze week), een betere installatie, leuke integratie met VSd, en volledige documentatie.

Voor alle vragen / problemen met de drop van ASP.NET MVC van deze week, kijk zeker ook eens op het ASP.NET MVC forum op www.asp.net.

Ik hoop dat jullie hiermee aan de slag kunnen,

Scott 

 

Published Saturday, April 19, 2008 8:24 PM by Joeri Pansaerts
Filed under: , ,

Comments

No Comments