Het ASP.NET MVC team is de laatste hand aan het leggen aan de nieuwe 'Preview 4' release die het later op de week hoopt uit te brengen. De Preview 3 release was vooral gericht op de afwerking van vele onderliggende centrale API's en uitbreidbaarheidsfactoren in ASP.NET MVC. Als je deze week start met de Preview 4, dan zal je meer en meer functies ontdekken die gebouwd zijn op de centrale funderingen en die heel wat productiviteit toevoegen.
Er zijn een aantal nieuwe functies en mogelijkheden in deze nieuwe versie, zoveel zelfs dat ik heb beslist om ze te verdelen over twee posts. De eerste post zal de nieuwe Caching, Error Handling en Beveilingsfuncties behandelen, alsook enkele testverbeteringen. In mijn volgende post komen de nieuwe AJAX functies aan bod die in deze release aanwezig zullen zijn.
Filter Interceptors begrijpen
Action Filter Attributen houden veel potentieel in wat uitbreidbaarheid betreft in ASP.NET MVC die overigens voor het eerst werd geintroduceerd met de "Preview 2" release. Met deze attributes kan je code toevoegen aan de request van een MVC Controller. Deze code kan uitgevoerd worden voor of na een Controller of diens Action methods uitvoering. Hierdoor kan je gemakkelijk functionaliteit groeperen en hergebruiken op een mooie declaratieve manier.
HIeronder vind je een voorbeeld van een supereenvoudige "ScottGuLog" filter die ik zou kunnen gebruiken om details te loggen over exceptions die opgedoken zijn tijdens de uitvoering van een request. Een custom filter implementeren is gemakkelijk, je moet de "ActionFilterAtribute' in een sub classe steken en de nodige methodes overriden om de code uit te voeren voor of nadat een Action method is aangevraagd op de Controller en voor of nadat een ActionResult in een antwoord wordt verwerkt.

Een filter gebruiken in een ASP.NET MVC Controller is gemakkelijk. Je moet het gewoon declareren als een attribuut op een Action Method, of op de Controller class zelf (in dat geval zal het van toepassing zijn
op alle Action Methods in de Controller):
In het bovenstaande voorbeeld zie je hoe twee filters toegepast worden. Ik heb aangeduid dat ik wil dat mijn "ScottGuLog" toegepast wordt op de 'About' action method en dat ik wil dat de 'HandleError' filter toegepast wordt op alle action methods van de HomeController.
Voorgaande preview releases van ASP.NET MVC maakten deze uitbreidbaarheid van filters mogelijk, maar er waren nog geen voorgebouwde filters aanwezig. ASP.NET Preview 4 bevat nu verschillende handige filters om output caching, errors en beveiliging te behandelen.
OutputCache Filter
De [OutputCache] filter biedt een gemakkelijke manier om ASP.NET MVC te integreren met de output caching functies van ASP.NET (met ASP.NET MVC preview 3 moest je zelf code schrijven om dit te bereiken). Om dit uit te proberen, wijzig de 'Message' waardeset in de 'Index' action method van de HomeController (gecreëerd door de VS ASP.NET MVC project template) om de tijd weer te geven:

Als je je applicatie doet werken, dan zul je zien dat de getoonde tijd wordt vernieuwd telkens je de pagina vernieuwt:

We kunnen output caching mogelijk maken voor deze URL door het [OutputCache] attribute toe te voegen aan onze Action Method. We zullen dit zo configuren dat het antwoord 10 seconden lang gecached wordt met de declaratie hieronder:

Als je nu op 'pagina vernieuwen' klikt dan zal je zien dat de tijdsaanduiding slechts om de 10 seconden wordt vernieuwd. Dit komt omdat de action method slechts om de 10 seconden aangeroepen wordt. Alle aanvragen tussen deze tijdsintervallen worden uit de ASP.NET output cache gefilterd (dit betekent dat er geen code hoeft uitgevoerd te worden en daardoor gaat het ook supersnel!). Bovenop de ondersteuning van tijdsduur, ondersteunt de OutputCache ook de standaard ASP.NET output cache met gevarieerde opties (varierend op parameters, headers, content encoding en custom logic). Bijvoorbeeld, het voorbeeld hieronder zou verschillende cached versies opslaan van de pagina, afhankelijk van de waarde van een optionele "PageIndex" QueryString parameter en automatisch de correcte versie genereren afhankelijk van de querystring waarde van de inkomende URL:

Je kan ook de Database Invalidation functie integreren in ASP.NET, waardoor je automatisch de cache kan ongeldig maken als een database waar de URL afhankelijk van is, gewijzigd is (tip: de beste manier om dit te doen is een CacheProfile sectie opzetten in je web.config en er dan naar refereren in het OutputCache attribute).
HandleError Filter
De [HandleError] filter biedt een manier om declaratief aan te duiden op een Controller of een Action method dat een vriendelijk error antwoord getoond moet worden als zich een error voordoet tijdens de verwerking van een ASP.NET MVC aanvraag. Om dit uit te proberen, voeg een nieuwe "TestController" toe aan een project en implementeer een action method om een exception te genereren zoals hieronder:

Als je je browser naar die URL leidt, dan zal het standaard een standaard ASP.NET errorpagina tonen om gebruikers op de fout te wijzen (tenzij je een <customErrors> sectie hebt gecreëerd in je web.config bestand):

We kunnen de HTML error die getoond wordt veranderen naar een vriendelijkere boodschap voor de eindgebruiker door een [HandleError] attribute aan toe te voegen aan onze Controller of aan onze Action Method op de Controller:

De HandleError filter zal alle exceptions cachen (ondermeer errors die gegenereerd worden wanneer View templates verwerkt worden), en toont een gepersonaliseerd Error antwoord als ze zich zouden voordoen. Standaard zal het proberen om een View template, "error" genaamd, in je project trachten aan te maken om een antwoord te genereren. Je kan de "Error" view plaatsen in dezelfde directory als je andere controllerspecifieke views (bijvoorbeeld: \Views\Test voor de TestController hierboven), of in de \Views\Shared folder (het zal eerst zoeken naar een controllerspecifieke errorview en als dat niet wordt gevonden, dan zal het zoeken in de shared folder, die de views bevat die door alle Controllers gedeeld worden). Visual Studio voegt nu automatisch een standaard "Error" view template toe aan de \Views\Shared folder als je een nieuw ASP.NET MVC Projects aanmaakt met de Preview 4:

Als we een [HandleError] attribute toevoegen aan onze TestController, dan zal dit standaard eindgebruikers een html errorpagina tonen zoals hieronder (merk op dat het de masterpage template aanneemt van het project, zodat de error boodschap geintegreerd is in de site). Je kan uiteraard de Error view template personaliseren zodat je om het even welke html en/of vriendelijkere errorboodschap kunt tonen. Hieronder wordt getoond wat je standaard krijgt.

Om ontwikkelaars te helpen is de standaard Error view template, die geintegreerd is in de nieuwe project template in Visual Studio, gemaakt om bijkomende error stack trace informatie te tonen als je de applicatie lokaal uitvoert:

Je kan dit afzetten door de code te verwijderen uit de Error view template, of door de <customErrors> op "off" te zetten in je web.config bestand. De [HandleError] filter zal standaard alle exceptions opvangen en verwerken die voorkomen tijdens een aanvraag. Je kan ook specifieke exception types specificeren die je wil cachen. Je kan ook gepersonaliseerde error views specificeren door het "ExceptionType" en de "View" eigenschappen van de [HandleError] attributes te specificeren:

In de bovenstaande code kies ik ervoor om gepersonaliseerde error views voor SqlExceptions en NullReferenceExceptions te tonen. Alle andere exceptions zullen getoond worden met de de standaard "Error" view template.
Authorize Filter
De [Authorize] filter biedt een manier om de beveiligingstoegang declaratief controleren op een Controller of een Action Method. Hierdoor kan je aanduiden dat een gebruiker ingelogged moet zijn, en kan je eventueel ook vereisen dat ze een specifieke gebruiker zijn in een specifieke beveiligingsrol om toegang te kunnen krijgen. De filter werkt met alle types authenticatie (waaronder Windows en formuliergebaseerde authenticatie). Het biedt ook ondersteuning om automatisch anonieme gebruikers door te verwijzen naar een login formulier wanneer nodig. Om dit uit te proberen, voeg een [Authorize] filter toe aan de "About" action in de HomeController, die standaard gecreëerd wordt door Visual Studio:

Een [Authorize] attribute declareren zoals hierboven wijst erop dat een gebruiker ingelogged moet zijn in de website om een "About" action te kunnen aanvragen. Als niet-ingelogde gebruikers trachten om de /Home/About URL aan te klikken, dan zullen ze geen toegang krijgen. Als de webapplicatie zo is geconfigureerd dat het Windowsgebaseerde authenticatie gebruikt, dan zal ASP.NET automatisch de gebruiker authenticeren door hun Windows login info te gebruiken, en indien in orde, dan kan de gebruiker verder. Als de webapplicatie is geconfigureerd om Formuliergebaseerde authenticatie te gebruiken, dan zal het [Authorize] attribute automatisch de gebruiker doorverwijzen naar een loginpagina zodat deze zich kan autentificeren (waarna hij toegang zal krijgen):

Het [Authorize] attribute laat je ook toe om toegang te verlenen aan specifieke gebruikers en gebruikersrollen. Bijvoorbeeld, als ik de toegang tot de "About" action zou willen limiteren tot mezelf en Bill Gates, dan zou ik het volgende kunnen schrijven:

Het is zeker niet aan te raden voor meer geavanceerde applicaties om gebruikersnamen te hardcoden in je code. Je kan beter een concept gebruiken van een bovenliggend niveau zoals "rollen" om permissies te definieren. Dan kan je de gebruikers apart in rollen verdelen (bijvoorbeeld, de active directory of een database gebruiken om de verdeling op te slaan). Met het [Authorize] attribute is het gemakkelijk om de toegang te beheren tot Controllers en Actions door de "Roles" eigenschap te gebruiken:

Het [Authorize] attribute is niet afhankelijk van een specifieke gebruikersidentiteit of role management mechanisme. Het werkt met het ASP.NET "User" object, dat uitbreidbaar is en waarmee je eender welk identificeersysteem kan gebruiken.
AccountController Class
Hierboven heb ik vermeld dat het [Authorize] attribute gebruikt kan worden met elk authenticatiesysteem of identiteitbeheersysteem. Je kan elk gepersonaliseerd login UI en / of gebruikersnaam/paswoord systeem schrijven of gebruiken. Om je wat op weg te helpen, bevat de ASP.NET MVC Project Template in Visual Studio nu een voorgebouwde "AccountController" met login views die een systeem voor formulierauthenticatie op basis van lidmaatschap integreert met ondersteuning voor inloggen, uitloggen, nieuwe gebruikers registreren en paswoorden wijzigen. Alle view templates en UI kunnen gemakkelijk gepersonaliseerd worden, los van de AccountController class of implementatie:

De Site.master template bevat nu ook UI in de rechterbovenhoek die login/logout functionaliteit biedt. Als je fomuliergebaseerde authenticatie gebruikt, dan zal het je je login vragen als je nog niet geidentificeerd werd:

En het toont een welkomstboodschap samen met een logout link als je geidentificeerd bent op de site:

Als je hierboven op de login link klikt, dan wordt je doorverwezen naar een loginscherm zoals hieronder zodat je je kan identificeren:

Nieuwe gebruikers kunnen klikken op de registreerlink om een nieuwe account te creëeren:

Error handing en error display is ook ingebouwd:

De AccountController class dat is toegevoegd aan nieuwe projecten maakt gebruik van de ingebouwde ASP.NET membership API om gebruikersgegevens te bewaren en te beheren (het Membership systeem gebruikt een provider API, waardoor alle back-end opslag kan ingeplugd worden en ASP.NET bevat ingebouwde providers voor Active Directory en SQL Server). Als je het ingebouwde Membership systeem niet wil gebruiken, dan kan je dezelfde AccountController action method signatures behouden. View templates, en Forms Authentication zijn zeer logisch opgebouwd en vervangen gewoon de gebruikersaccount logica binnen de AccountController class. Voor de volgende ASP.NET MVC preview release plannen we de inbedding van de interactielogica tussen de Account Controller en het gebruikersidentiteitssysteem achter een interface. Dit zal het gemakkelijker maken om je eigen opslagsysteem in te pluggen (zonder een volledige membership provider te moeten implementeren). Ook zal het gemakkelijker zijn om dit en de AccountController te unit testen.We hopen vooral dat dit een goede manier zal zijn om mensen snel aan de slag te helpen zodat ze een goed werkend afgewerkt beveiligingssysteem hebben van zodra ze een nieuw project creëren.
TempData testen
Een laatste verbetering die ik graag ter sprake breng in deze eerste preview 4 post is die aan de Controller class waardoor je gemakkelijker de TempData collectie kan unit testen. Met de TempData eigenschap kan je data opslaan die je wil houden voor een toekomstige aanvraag van een gebruiker. De semantiek zit zo ineen dat het slechts een toekomstige aanvraag blijft bestaan (daarna wordt het verwijderd). Het wordt over het algemeen gebruikt voor MVC scenario's, waarin je een client-side redirect wil uitvoeren om de URL in de browser te veranderen en een eenvoudige manier wil om scratch data te bewaren. In vorige ASP.NET MVC preciew moest je objecten 'namaken' om de TempData collectie te testen. Met Preview 4 is dit niet langer nodig, ook andere setups zijn niet meer nodig. Je kan nu objecten toevoegen en verifieren binnen de TempData collectie van de controller en dit onmiddellijk in je Unit tests (bijvoorbeeld: de Tempdata eigenschap van een controller bepalen, voor zijn action method aan te roepen verifieren of een action method de TempData heeft geupdate na terugkeer). De opslagsemantiek van de TempData collecite is nu vervat in een aparte TempDataProvider eigenschap.
Conclusie
Hopelijk biedt de bovenstaande post een snelle blik op het aantal nieuwe functies en veranderingen in de ASP.NET MVC Preview 4. Mijn volgende post over ASP.NET MVC Preview 4 zal de nieuwe AJAX functionaliteit behandelen en zal ook demonstreren hoe je er gebruik van kan maken.
Hopelijk kan je hiermee aan de slag,
Scott