ASP.net : HTML Server-controls

  1. Wat zijn HTML-servercontrols ?
  2. Een gewoon HTML-formulier
  3. ASP.net serverformulier
  4. __VIEWSTATE
  5. Actie ondernemen
  6. Achtergrond
  7. Viewstate aangeven
  8. Html servercontrols en stijlen
  9. Reageren op events

Wat zijn HTML-servercontrols ?

We weten dat wanneer een pagina, die een eerste keer wordt aangevraagd op de server, wordt gecompileerd in een klasse (binnenin een .dll-bestand). Deze klasse kan uitgevoerd worden telkens de pagina wordt opgevraagd. De server stuurt zo alle statische HTML en client-side code terug de naar client. We hebben hiermee nu geen interactie meer op de server.

Controls die echter gemarkeerd worden met het attribuut runat="server" worden op de server objecten van de klasse Page. Dit betekent dat je server-side code kan schrijven die deze objecten beïnvloedt : we hebben toegang tot de eigenschappen en methoden van deze objecten en kunnen op de server reageren op events die zich voordoen binnen deze objecten (klikken, keuzes die gemaakt worden,...). Om op events in formulierelementen te reageren op de server maakt ASP.NET gebruik van de postback-architectuur : de pagina wordt naar dezelfde pagina op de server teruggestuurd wanneer controls worden beïnvloed. Wanneer de gebruiker op een knop op een formulier klikt wordt het formulier opnieuw naar de server gestuurd (postback) en een eventroutine wordt op de server uitgevoerd. Belangrijk is ook het feit dat Server Controls zich niet beperken tot HTML-formulierelementen, je kunt ook andere HTML-tags als server-control markeren !

Een gewoon HTML-formulier

Wanneer je het onderstaande formulier verstuurt, wordt dezelfde pagina opnieuw geladen. Merk op dat alle gegevens die je hebt ingevuld verloren zijn gegaan: http is stateless !
htmlform.html
<html>
<head>
	<title>HTML-form</title>
</head>
<body>
<form id="Form1" action="htmlform.html">
<table>
<tr>
       <td>Naam :</td>
       <td><input type="text" id="naam"></td>
</tr>
<tr>
       <td>Voornaam : </td>
       <td><input type="text" id="voornaam"></td>
</tr>
<tr>
       <td>Aantal :</td>
       <td><select id="aantal">
			      <option value="1">1</option>
			      <option value="2">2</option>
			      <option value="3">3</option>
		       </select>
		</td>
</tr>
</table>
	<input type="submit" value="klik me"> 
</form>
</body>
</html>

Een ASP.net serverformulier

ServerForm.aspx
<%@ PAGE language="c#" %>
<html>
<head>
	<title>Serverform</title>
</head>
<body>
<form id="Form1" runat="server">
<table>
<tr>
       <td>Naam :</td>
       <td><input type="text" id="naam" runat="server"></td>
</tr>
<tr>
       <td>Voornaam : </td>
       <td><input type="text" id="voornaam" runat="server"></td>
</tr>
<tr>
       <td>Aantal :</td>
       <td><select id="aantal" runat="server">
			      <option value="1">1</option>
			      <option value="2">2</option>
			      <option value="3">3</option>
		       </select>
		</td>
</tr>
</table>
	<input type="submit" value="klik me" runat="server">
</form>
</body>
</html>

__VIEWSTATE

Bekijk voor bovenstaande pagina de broncode in de browser:
<html>
<head>
	<title>Serverform</title>
</head>
<body>
<form name="Form1" method="post" action="ServerForm.aspx" id="Form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTk4NDU0ODIyMWRkl7VvKXMytCE+87WVlXk5UmBICJQ=" />
</div>

<table>
<tr>
       <td>Naam :</td>
       <td><input name="naam" type="text" id="naam" /></td>
</tr>
<tr>
       <td>Voornaam : </td>
       <td><input name="voornaam" type="text" id="voornaam" /></td>
</tr>
<tr>
       <td>Aantal :</td>
       <td><select name="aantal" id="aantal">
	<option value="1">1</option>
	<option value="2">2</option>
	<option value="3">3</option>
</select>
		</td>
</tr>
</table>
	<input name="Submit1" type="submit" id="Submit1" value="klik me" />

<div>

	<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBQKKw9nZBwLn3YvMDgKEhan0BwLqkpGKCgLVo8avDpzM1csbPfbYOcjuvaxCmzEqJ12a" />
</div></form>
</body>
</html>
Aangezien de browser enkel HTML en client-side code zoals Javascript ondersteunt is er van de server-side ASP.NET code geen spoor te vinden. Je merkt echter dat de code er in de browser helemaal anders uitziet dan de code die werd uitgevoerd op de server.

Elk element op de pagina dat een attribuut runat="server" draagt wordt bij het aanroepen van de pagina door de server onderhanden genomen.

De tags verliezen hun runat-attribuut (hier is de browser niks mee) maar krijgen eventueel een aantal andere attributen. Je merkt in de form-tag dat de method is ingesteld op post en de action op de naam van de huidige pagina. Vooral dit laatste is heel belangrijk : het is een illustratie van de postback-architectuur waarvan zopas sprake.

Je merkt ook dat de formulierelementen (form en input) een name en/of id hebben gekregen. Deze naam dient om bij het terugposten van de pagina te zien of er aan deze control iets is veranderd (moet een event getriggerd worden ?). Als de server moet bepalen of er een verandering is opgetreden, dan moet je bij het terugposten de huidige situatie ook meegeven, want het http-protocol is 'stateless' en behandelt elke aanvraag als volstrekt onafhankelijk.

Vandaar het hidden veld __VIEWSTATE : hierin staat in een voor de ASP.NET-server begrijpelijke code de situatie zoals nu op het scherm is afgebeeld. Doe je als gebruiker een actie die het versturen van het formulier tot gevolg heeft, dan kan de server bepalen wat er veranderd is en op die actie reageren.

Wanneer je het formulier invult en verstuurd zal je merken dat alle informatie die je hebt ingevuld bewaard is gebleven!

Actie ondernemen

We maken een kleine toepassing waarbij we detecteren of een gebruiker op een knop heeft geklikt.
<%@ PAGE language="c#" %>
<html>
<head>
	<title>Knop</title>
	<SCRIPT language="c#" runat="server">
	private void KnopKlik(object sender, System.EventArgs e) {
		tekstvak.InnerHtml = "U heeft op de knop geklikt !";
	}
	</SCRIPT>
</head>
<body>
<form runat="server">
	<p><div style="border:solid;border-width:1;width:200" id="tekstvak" runat="server"/></p>
	<p><input type="submit" value="klik me" onserverclick="KnopKlik" runat="server"></p>
</form>
</body>
</html>

Je kan met het attribuut onserverclick het klikken op de submit-button server-side opvangen.

Achtergrond

HTML Server Controls zijn elementen die gedefiniëerd zijn in de namespace System.Web.UI.HtmlControls. Hierin zitten een aantal basisklassen waarvan de controls overerven (meer over klassen en overerving verderop in de cursus). De basisklasse voor alle HTML Controls is de System.Web.UI.HtmlControls.HtmlControl klasse. Deze klasse bevat eigenschappen, methoden die gemeenschappelijk zijn voor alle HTML Controls.

Via de Visual Studio.net 2003 Documentation > .NET Framework > Reference > Class Library of met de ClassBrowser die wordt meegeleverd met de .NET Web Matrix kan je deze klassen onderzoeken en kijken welke eigenschappen en methodes voorhanden zijn.

Opmerking : de eigenschap InnerHtml die we in het vorig voorbeeld hebben gebruikt, maakt deel uit van de System.Web.UI.HtmlControls.HtmlContainerControl klasse, die gebruikt wordt voor containerelementen : tags die een sluittag moeten hebben : I, B, DIV, ... Met behulp van de classbrowser kanje zien dat een aantal elementen een voorgedefiniëerde klasse hebben binnen System.Web.UI.HtmlControls: hyperlinks (<,a runat="server">) worden bijvoorbeeld op de server vertaald als HtmlAnchor-klassen.

Naast deze voorgedefiniëerde klassen bestaan nog HTML-elementen die hier geen tegenhanger vinden. Deze elementen worden dan omgezet in een object van de System.Web.UI.HtmlControls.HtmlGenericControl klasse. Deze klasse dient dus voor het afhandelen van Server Controls die geen klasse hebben binnen System.Web.UI.HtmlControls.

Viewstate aangeven

Wanneer een control gemarkeerd is met runat="server" wordt de waarde ervan bewaard bij versturen van de pagina naar de browser, in het verborgen formulierveld __VIEWSTATE. Soms zal je voor een bepaalde control niet willen dat deze status wordt bewaard. Door het attribuut EnableViewState op false in te stellen wordt voor de respectievelijke control geen status bewaard.

Html Servercontrols en stijlen

Je kunt met ASP.NET Server Controls ook gebruik maken van stylesheets en de opmaak vanop de server vastleggen:
Stijl.aspx
<%@ PAGE language="c#" %>
<html>
<head>
	<title>Stijl</title>
	<SCRIPT language="c#" runat="server">
	private void Page_Load(object sender, System.EventArgs e) {
		info.InnerHtml = "Opgemaakte tekst";
		info.Style["font-family"] = "Courier new";
		info.Style["font-weight"] = "Bold";
		info.Style["font-size"] = "18pt";
		info.Style["margin-left"] = "4cm";
	}

	</SCRIPT>
</head>
<body>
<div id="info" runat="server" />
</body>
</html>
Bron in de browser:
<html>
<head>
	<title>Stijl</title>
	
</head>
<body>
<div id="info" style="font-family:Courier new;font-weight:Bold;font-size:18pt;margin-left:4cm;">Opgemaakte tekst</div>
</body>
</html>

Reageren op events

Wanneer we gebruik maken van Server Controls worden acties die de gebruiker onderneemt (klikken op een knop, een keuze veranderen in een lijst) op de server afgehandeld. Er zijn twee events die je hiervoor kan gebruiken : ServerClick en ServerChange.

Serverclick

Dit event heb je reeds leren kennen in knop.aspx, hier gaan we er wat meer in detail op in.
Serverclick
<%@ PAGE language="c#" %>
<html>
<head>
	<title>Serverclick</title>
	<SCRIPT language="c#" runat="server">
	private void MijnCode(Object objSender,EventArgs objArgs){
	       Control c = (Control)objSender;
		   divResultaat.InnerHtml += "Klik op knop : <B>" +c.ID +"</B><BR>";
	}

	private void MijnfiguurCode(Object objSender ,ImageClickEventArgs objArgs){
	   HtmlInputImage c = (HtmlInputImage)objSender;
	   divResultaat.InnerHtml += "Klik op figuur " +c.ID
	   +" <I>--> xpos : " +objArgs.X
	   +" / ypos : " +objArgs.Y +"</I><BR>";
	}
	</SCRIPT>
</head>
<body>
<form runat="server">
	<input id="MijnKnop" type="button" value="Mijn knop" onserverclick="MijnCode" runat="server" />
	<input id="MijnSubmitKnop" type="submit" value="Mijn submitknop" onserverclick="MijnCode" runat="server" />
	<input id="figuur" type="image" src="../images/vraag.jpg" onserverclick="MijnfiguurCode" runat="server" />
</form>
<div id="divResultaat" runat="server" />
</body>
</html>

Telkens op een knop of op de figuur wordt geklikt verschijnt een boodschap op het scherm. Wanneer op een van de knoppen wordt geklikt wordt de routine MijnCode gestart, wanneer je op de figuur klikt wordt MijnFiguurCode uitgevoerd.
Beide routines voegen een zin toe aan de InnerHtml eigenschap van de divisie divResultaat. Belangrijk hierbij is dat je de code voor het afhandelen van een event aan meerdere controls kan koppelen, zoals hier met de twee knoppen.

De eventhandler-routines ontvangen twee parameters :

Serverchange

Dit event kan je gebruiken bij controls die niet automatisch voor een repost naar de server zorgen, waar je als gebruiker m.a.w. niet op klikt : HtmlInputText, HtmlInputCheckBox, HtmlInputRadioButton, HtmlSelect,...

Wanneer sinds de vorige post iets aan deze control is veranderd, wordt het ServerChange event uitgevoerd.

ServerChange.aspx
<%@ PAGE language="c#" %>
<html>
<head>
	<title>ServerChange</title>
	<SCRIPT language="c#" runat="server">
	private void MijnCode(Object objSender ,EventArgs objArgs){
	   Control c = (Control)objSender;
	   divResultaat.InnerHtml += "Verandering vastgesteld : <B>" +c.ID +"</B><BR>";
	}
	private void MijnLijstCode(Object objSender,EventArgs objArgs){
	    HtmlSelect c = (HtmlSelect)objSender;
		divResultaat.InnerHtml += "Verandering vastgesteld : <B>"
		+c.ID +"</B>" +"</I><BR>"
		+"Index = <i>" +c.SelectedIndex +"</i><BR>"
		+"Tekst = <i>" +c.Items[c.SelectedIndex].Text +"</i><BR>"
		+"Waarde = <i>" +c.Items[c.SelectedIndex].Value +"</i><BR>";
	}
	</SCRIPT>
</head>
<body>
<form runat="server">
	<input id="MijnTekst" type="text" value="Standaardtekst" onserverchange="MijnCode" runat="server" />
	<select id="MijnLijst" onserverchange="MijnLijstCode" runat="server">
		<option value="waarde 1">Optie 1</option>
		<option value="waarde 2">Optie 2</option>
		<option value="waarde 3">Optie 3</option>
	</select>
	<input id="MijnCheckBox" type="checkbox" onserverchange="MijnCode" runat="server" />
	<input type="submit" value="verstuur" />
</form>
<div id="divResultaat" runat="server" enableviewstate="false"/>
</body>
</html>

Meer tutorials:
leer ook: html | xhtml | css | asp | asp.net | c# | ado.net | linq | ajax | java | javascript
Valid HTML 4.01! Valid CSS! © - Cursusweb