Migreren naar ASP.NET deel 1
Door Michiel van Otegem
10 april 2003
Door de komst van het .NET Framework en ASP.NET, denk je mogelijk aan het migreren van je applicaties.
Uiteraard profiteren nieuwe applicaties van ontwikkelen in ASP.NET, maar als je
huidige applicaties prima draaien, dan denk je wel even goed na over migreren
van bestaande applicaties. De vraag is Waarom zou ik een bestaande applicatie
migreren?, en nog belangrijker Als ik besluit tot migreren, hoe pak ik dat
dan aan?. In deel I van dit artikel behandel ik het waarom, in deel II het
hoe.
Als je ooit migratie projecten hebt gedaan, dan weet je dat dit erg vervelend werk kan zijn.
In gevallen waar er veel verschillen zijn tussen de functionaliteit en API van
het bron en doel platform, kan de enige oplossing zijn de gehele applicatie te
herontwerpen en opnieuw te implementeren. Zelfs als dit niet zo is, is migreren
een nauwgezet proces, dat veel tijd vergt. Om deze reden heb je mogelijk helemaal
geen zin om te migreren als je huidige applicaties al prima werken. Je moet de
voordelen van migreren afwegen tegen de last van het migratieproces. Als je dit
overweegt, dan zijn er waarschijnlijk een aantal belangrijke punten om naar te kijken.
Voor een web platform zijn de belangrijkste punten prestatie (snelheid en schaalbaarheid),
stabiliteit, beveiliging. Vanuit de ontwikkelkant gekeken zijn gebruikersgemak en kracht
van de programmeertaal/-omgeving ook erg belangrijk. Voordat ik echt in ga op de migratie
zelf, zal ik eerst deze punten behandelen.
ASP.NET prestatie
Prestatie is een van de belangrijkste factoren in een web omgeving, omdat je mogelijk duizenden
gebruikers moet kunnen bedienen. Daarom vraagt het maken van goede web applicaties een andere
aanpak dan traditionele (client/server) ontwikkeling. De tijd om een verzoek door
te voeren moet tot een minimum beperkt worden en moet, indien mogelijk, zo min mogelijk
systeembronnen gebruiken. ASP.NET verschaft verschillende mechanismen om met zulke zaken om
te gaan, een aantal hiervan hebben flink wat ruimte nodig (een groot geheugen helpt dus zeker).
Om de prestatie te verbeteren ten opzichte van ASP, compileert ASP.NET pagina´s tot Microsoft
Intermediate Language (MSIL), wat platform onafhankelijke code is vergelijkbaar
met gecompileerde Java code (Java byte code). De code MSIL code wordt JIT gecompileerd
naar native code op het moment dat dit nodig is, resulterend in een laag geheugen
gebruik, omdat niet alle code perse hoeft te worden gecompileerd in geheugen. Al deze
processen worden automatisch gedaan, zodat je je pagina´s gewoon kan blijven schrijven,
opslaan en draaien, maak je daar dus maar niet druk om. In ASP worden pagina´s ook
´gecompileerd´ en bewaard in een geheugen cache. Pagina´s kunnen eventueel verwijderd
worden uit deze cache, omdat de cache vol is, de server is herstart of omdat de gecachte
pagina ongeldig is. ASP.NET bewaart de gecompileerde pagina´s echter ook op een tijdelijke
disk locatie, waarvandaan het een pagina zal lezen als deze niet langer in de geheugen cache zit.
De gecompileerde pagina zal dus blijven bestaan als de server opnieuw opgestart wordt, en wordt
alleen ongeldig als de bronpagina veranderd is. De prestatie verbetering van deze aanpak ten
opzichte van ASP is aanmerkelijk. Tests die een 3000 regels tellende ASP pagina (met een aantal
COM componenten) vergelijkt met een zelfde pagina in ASP.NET (met .NET componenten) laat zien
dat de code prestatie van ASP.NET tussen 2.5-3.0 keer beter is als ASP. Of deze pagina is
geschreven in VB.NET of C# maakt weinig uit, en kan waarschijnlijk, waarbij de verschillen
waarschijnlijk aan de programmeerstijl liggen, aangezien de VB.NET en C# versies theoretisch
beide gecompileerd zijn tot min of meer dezelfde MSIL.

Een andere belangrijke prestatie verbeteraar in ASP.NET is de prestatie bij het werken
met gegevensbronnen (zoals een database). Dit kan voornamelijk toegewezen worden
aan de wijze waarop ASP.NET omgaat met gegevens uit een gegevensbron. Om de minste
impact op de systeem bronnen te maken, zijn gegevensoperaties in ASP.NET erop gericht
de gegevens snel te verkrijgen en vervolgens de verbinding zo snel mogelijk te
sluiten. Om dit mogelijk te maken heb je de mogelijkheid om ASP.NET het openen en
sluiten van verbindingen te laten verrichten. Dit betekent dat de verbinding onmiddellijk
wordt geopend voordat de gegevens worden verkregen en wordt gesloten zodra de
gegevensoverdracht is gebeurd. Elke manipulatie van de gegevens wordt gedaan nadat
de verbinding is gesloten, zodat deze bronnen gebruikt kunnen worden voor andere
verzoeken. Tests die 50 rijen uit een gemiddelde tabel in SQL Server haalden, hebben
aangetoond dat deze benadering tussen de 1.75-5.0 keer zo snel is als in ASP, afhankelijk
van de methode die gebruikt is om de gegevens weer te geven (waarvan er weinig zijn).
Behalve de toegenomen prestatie van de code en operaties met gegevens biedt
ASP.NET een aantal geraffineerde mechanismen om de prestatie nog meer te verbeteren.
Pagina´s die gebouwd zijn met een gegevensbron en die server controls gebruiken om
gegevens weer te geven, hoeven slechts 1 keer gemaakt te worden voor elke gebruiker.
ASP.NET bewaart een viewstate voor deze controls, zodat als er een postback naar
dezelfde pagina gebeurt, de pagina kan worden weergegeven zonder de moeite te doen
de gegevens weer uit de database te halen (mits de gegevens in de betreffende controls
niet veranderd hoeven te worden natuurlijk). Bovendien kan de HTML van een pagina
die hieruit resulteert in geheugen gecached worden voor een bepaalde tijd,
waarbij ASP.NET dit HTML resultaat naar de browser stuurt als er een verzoek voor
dezelfde pagina binnenkomt. Dit wordt Output Caching genoemd en werkt zelfs voor
verzoeken met verschillende headers, querystrings, of indien nodig verschillende
browsers die andere HTML output vereisen. Op pagina´s met veel verkeer
(b.v. de MSN home page), bespaart dit veel overhead, zelfs als de pagina gecached
wordt voor slechts 30 seconden.
Ontwikkelaars zal de nieuwe applicatie cache ook erg bevallen, die toestaat om
items te cachen op een applicatie scale, gelijk aan het Applicatie object, maar
met veel opties. In tegenstelling tot het Applicatie object, zal de cache zichzelf
automatisch opschonen als het systeem weinig geheugen heeft. Om dit in de hand te
houden, kunnen gecachte items een voorrang gegeven worden. Ongeldig verklaren
van gecachte items kan tijd gebaseerd gedaan worden, of afhankelijk van bestanden,
mappen of andere objecten in de applicatie. Bovendien wordt er een event afgevuurd
als een item is verwijderd uit de cache waaraan je je eigen custom functie kunt toevoegen.
De beste manier om te laten zien dat het bovenstaande ook
echt zo is, is met een aantal simpele voorbeelden. De onderstaande code geeft
een pagina weer met een klikbare kalender om een datum te selecteren.
Tests gedaan op een build tussen beta 1 en beta 2 hebben aangetoond dat ASP.NET veel
sneller is dan welke concurrerende technologie ook (noot: sinds het beschikbaar
komen van versie 1.0 zijn er meerdere tests gedaan, welke je kunt vinden op
http://www.gotdotnet.com). Met concurrerende technologie bedoel ik gelijksoortige
pagina/scripting gebaseerde technologieën zoals ASP, JSP en PHP. Apache modules
geschreven in C worden niet gezien als concurrerende technologie, omdat ze op een
ander programmeer paradigma gebaseerd zijn. Momenteel is de snelste van de concurrerende
technologieën waarschijnlijk JSP op een van de grote J2EE platformen (noot: vanwege de
licentieovereenkomst mag niet bekend worden gemaakt welke). Tests die gebruik maken van
PC Magazines Nile Application Test (een typische eCommerce applicatie) hebben aangetoond
dat op een 2 processor systeem ASP.NET met SQL Server 2000 bijna twee keer zo goed presteert
als het J2EE platform met een concurrerend DBMS (ook hier geen naam vanwege licentieovereenkomst),
op een 4 processor machine is dit zelfs twee en een half keer zo goed. De resultaten van
ASP vs. ASP.NET zijn zelfs nog dramatischer als je waarschijnlijk zou verwachten van het
bovenstaande. De Nile Application Test, test code prestatie voornamelijk met database
operaties. In deze applicatie zijn er niet veel pagina´s die kunnen profiteren van Output
Caching en een aantal andere leuke truckjes die ASP.NET heeft. Applicaties die wel gebruik
kunnen maken van deze punten geven een nog grotere prestatie verbetering.

PC Magazine Nile Application test (*bron: Microsoft)
ASP.NET stabiliteit
De prestatie verbeteringen zoals besproken hierboven zijn niet van erg veel nut als jouw applicatie
niet stabiel is en vaak crasht tijdens werking. De huidige bouw van ASP.NET is echter ongelooflijk stabiel.
Omdat deze stabiliteit het resultaat is van mechanismen die onderdeel zijn van het .NET Framework en
niet zozeer ASP.NET, kan dezelfde stabiliteit worden verwacht van Windows applicaties die in
.NET geschreven zijn, ook wel WinForms applicaties genoemd.
Een belangrijke factor in deze stabiliteit is de Common Language Runtime. Code die gebruik maakt
van de CLR (via de compiler) is managed code. Dit betekent dat de code wordt gecontroleerd bij
runtime om zeker te weten dat het geen operaties uitvoert die het systeem in gevaar kunnen brengen,
zoals het schrijven naar een geheugenlocatie die buiten de procesruimte ligt (en mogelijk in de
procesruimte van een andere applicatie). Een ander voordeel van managed code is dat het geheugen
beheerd wordt en er garbage collection plaatsvindt op variabelen en objecten. Dit voorkomt
geheugenlekken die erg gewoon zijn in ASP applicaties.
Een andere belangrijke factor in de stabiliteit is de manier waarop ASP.NET
omgaat met processen die zijn vastlopen of die crashen. ASP.NET heeft een geavanceerd
opsporingsmechanisme dat processen die crashen, blokkeren of een bepaald geheugenlek
hebben opspoort. Processen die problemen veroorzaken worden geïsoleerd. Een nieuw proces wordt
dan gestart om nieuwe verzoeken te verwerken, terwijl het oude proces actief blijft
om verzoeken af te handelen waar het mee bezig was. Als deze geïsoleerde processen niet
zelf stoppen, dan zal ASP.NET ze uiteindelijk stoppen.
Een probleem dat zal ontstaan als je een applicatie migreert, is dat niet alle code managed code
zal zijn, tenzij je besluit de gehele applicatie in .NET code te herschrijven. Zolang jouw
applicatie ´oude´ COM componenten gebruikt, zal het unmanaged code bevatten en derhalve
niet zo stabiel zijn als mogelijk is. Er is ook een behoorlijke prestatie penalty voor
het gebruik van oude componenten. Het maakt overigens geen verschil of dit componenten
zijn die je zelf gemaakt hebt, ze van third party verkopers komen, of onderdeel zijn van
het operating system zelf. Het .NET framework is gebaseerd op een geheel nieuwe structuur
en het gebruik van oude componenten wordt alleen gedaan om achterwaartse compatibiliteit te
verzorgen. Als je de broncode van een component hebt dat de applicatie gebruikt, dan kan
het een goed idee zijn om dat component ook te migreren. Als componenten die worden gebruikt
door andere applicaties gemigreerd moeten worden, is dat geen enkel probleem. Het oude component
kan bestaan naast het nieuwe .NET component. Het nieuwe component wordt in feite niet eens
geregistreerd zoals het oude en bestaat alleen in de ruimte van de applicatie waar hij onderdeel
van is. Als je het wilt gebruiken in een andere applicatie, dan moet je het daarheen kopiëren.
Dit is heel wat anders dan het COM idee van eenmaal registreren, en in elke applicatie gebruiken,
en voorkomt daardoor heel wat compabiliteits zaken.
ASP.NET beveiliging
In tegenstelling to ASP, is ASP.NET niet echt een onderdeel van Internet Information Server.
ASP.NET neemt het over als een ASP.NET bestand wordt aangevraagd. Dit betekent dat ASP.NET
zich ook zelf met beveiliging bezighoudt. Alle ASP.NET applicatie instellingen staan in een
bestand dat web.config heet. Web.config is een XML bestand dat alle applicatie instellingen
bevat, inclusief alle beveiligingsinstellingen. Je kan deze instellingen van elke submap van
een applicatie ook beheren door er een aparte web.config in te plaatsen. De submap zal alle
instellingen van de hoofdmap erven, behalve als ze overschreven worden door het web.config
bestand in die submap. De hoofdmap erft de instellingen van de machineconfiguratie die staat
in machine.config. Net zoals de basisconfiguratie van IIS, verzorgt machine.config de basisinstellingen
voor alle ASP.NET applicaties. Dit is vooral handig als je met verschillende instelling van je
ontwikkel en productie omgeving werkt. Omdat web.config gewoon een bestand is, is het erg eenvoudig
om nieuwe instellingen naar de productie omgeving te kopiëren.
Alle beveiligingsonderdelen behandelen behoort niet tot de strekking van dit artikel,
maar het is wellicht interessant om te weten dat er veel identificatie en autorisatie onderdelen
deel uitmaken van ASP.NET. Een aantal van deze features, zoals Microsoft Passport gebaseerde identificatie,
zijn nieuw. Andere features konden voorheen geïmplementeerd worden door custom ISAPI filters of third party producten te gebruiken.
In vorige versies van ASP, was het mogelijk om een custom pagina te maken om jouw fouten af te handelen.
Dit was nodig voor een betere gebruikerservaring, maar ook om een hacker niet in staat te stellen zijn
hack te perfectioneren op basis van de foutinformatie. Een probleem echter is dat dit je verhindert om
applicaties op de productie server te debuggen. Om deze situatie te verhelpen, kan je nu ASP.NET configureren
om een custom foutpagina te laten op aan remote browsers. De browser op de locale machine kan nog steeds
e gehele fout te zien krijgen en zodat je de fout kunt opsporen.
ASP.NET ontwikkeling
ASP.NET is radicaal anders in aanpak dan ASP. ASP.NET is bijvoorbeeld gebaseerd op een compleet object
georiënteerd model en alle talen die zich richten op de Common Language Runtime zullen zo werken. Je ASP
ontwikkelkennis is echter zeker niet overbodig. Veel van de bekende ASP kenmerken hebben de cross-over naar
ASP.NET overleefd. De ASP objecten (e.g. Response object, Request object, Application object) zijn er nog steeds,
maar veel van hen hebben flinke veranderingen ondergaan. Deze veranderingen zijn echter vooral toevoegingen aan de
originele functionaliteit en hebben derhalve geen invloed op achterwaartse compatibiliteit, wat erg belangrijk is
voor migratie processen. Zoals gezegd zijn je ASP vaardigheden niet overbodig, maar je moet wel veel leren over tal
van nieuwe objecten. De meeste COM objecten die beschikbaar waren, hebben een nieuwe implementatie binnen het .NET Framework.
Je kan deze oude objecten zoals gezegd nog steeds gebruiken, maar tegen een behoorlijk prestatieverlies. Een goed voorbeeld
van de veranderingen is te zien in data access. Data access in het .NET Framework verschilt zo van ADO waar je mee werkte,
dat je het bijna niet herkent. Dat gezegd hebbende, heeft het ook duidelijk meer kracht en is zo veranderd dat het veel beter
past in een webapplicatie. Behalve dat het veel minder code nodig heeft, kan het op zo´n manier gebruikt worden dat het automatisch
een database verbinding opent en sluit, zodat de code ook nog eens veel efficiëntere. Omdat openen en sluiten van de database
verbinding automatisch gebeurt, kan het zo geregeld worden dat het zo min mogelijk bronnen gebruikt.
Buiten ASP.NET, is de gehele .NET API duidelijk anders als zijn oudere broer, de Win32 API. In tegenstelling tot de Win32 API
echter, is de gehele .NET API te gebruiken in ASP.NET applicaties. In essentie is er niet langer een verschil tussen het maken
van een webapplicatie en een Windows applicatie. Je hebt hetzelfde mate van toegang tot het onderliggende systeem. Dit betekent
dat je als ontwikkelaar zeer veel macht hebt (die je verstandig moet gebruiken
).
Behalve dat je minder code nodig hebt voor gewone taken, is de snelheid waarmee nieuwe applicaties gemaakt kunnen worden met ASP.NET
enorm verbeterd en versimpeld door het gebruik van server-controls. Deze controls zijn een beetje hetzelfde als het Ad Rotator object
in ASP (er is nu ook een nieuwe Ad Rotator control) en genereren HTML, niet ActiveX controls of iets dergelijks. Erg handig is het
feit dat ze worden toegevoegd aan een pagina met tags die lijken op HTML tags, wat het erg begrijpelijk en bruikbaar maakt voor designers.
In een typische ASP naar ASP.NET migratie, gebruik je deze controls niet erg veel. De uitzondering daarop kan de genoemde Ad Rotator
control zijn, die nu werkt gebaseerd op een XML bestand en die een aantal toegevoegde eigenschappen heeft.
Een van de belangrijkste veranderingen in ASP.NET is state management. In ASP kon je cookies en verborgen velden in formulieren gebruiken
om state management te doen, of het Session object gebruiken. De laatste echter had grote schaalbaarheidsproblemen, veel ontwikkelaars
kozen voor een custom implementatie, vaak met gebruik van een database, omdat cookies en formulier velden erg veel werk vereisen.
In ASP.NET is state management iets totaal anders. Nieuw gemaakte pagina´s (of WebForms) kunnen profiteren van automatisch state management
van de pagina zelf. Dit betekent dat je in een nauwkeurig ontworpen applicatie geen Session object hoeft te gebruiken zoals voorheen.
In gevallen waar je nog steeds een Session object gebruikt voor state management, kan je kiezen voor verschillende manieren waarop het
Session object de gegevens opslaat. Normaal worden alle gegevens nog steeds in het geheugen opgeslagen, maar je kunt ook gebruik maken
van een aparte State Server of een database, zodat je de sessiegegevens kunt delen tussen verschillende servers in een webfarm.
Je hoeft voor het Session object nu overigens niet perse meer een cookie te gebruiken voor de Session ID, die kan nu ook in de URL
gezet worden als je er niet op vertrouwt dat iedereen die je site bezoekt cookies accepteert.
Migratie proces
Dit artikel laat zeker niet het complete beeld zien van de voordelen van migreren naar ASP.NET. Daar zouden meerdere artikelen voor
nodig zijn, of zelfs een geheel boek. Het laat echter wel zien dat migreren naar ASP.NET enorme voordelen heeft.
De migratie zelf van een ASP applicatie naar ASP.NET zal in deel 2 van dit artikel behandeld worden.
Op dit moment kan ik wel zeggen dat migreren van bestaande pagina´s niet erg moeilijk is. In feite kunnen
pagina´s met gewone operaties binnen enkele minuten gemigreerd worden, zoals ik zal demonstreren in het
volgende deel, waar we zullen kijken naar verschillende code voorbeelden in zowel VB/VBScript als JavaScript.
Pagina´s met een erg ongebruikelijke functionaliteit, zoals communicatie met een legacy systeem, zullen een
stuk moeilijker te migreren zijn. Zulke applicaties zullen mogelijk gedeeltelijk gemigreerd worden, wat mogelijk is,
omdat ASP en ASP.NET pagina´s in dezelfde map kunnen draaien zonder elkaar in de weg te zitten. Het enige nadeel is
dat ze niet dezelfde Applicatie en Sessie objecten kunnen gebruiken. Het zullen twee verschillende applicaties zijn
die naast elkaar draaien in dezelfde map.
Dit artikel is eerder
verschenen in Code Magazine (issue 3, 2001) onder de naam "Migrating to ASP.NET part I
".
|