Delphi for .NET, ASP.NET en Code Behind |
Let op: Ik maak voor dit artikeltje gebruik van de Delphi for .NET preview command-line compiler met Update 3 (van februari 2003) - mocht er inmiddels een nieuwe(re) update beschikbaar zijn, dan heb je kans dat het probleem dat we straks tegenkomen inmiddels reeds verholpen is.
ASP.NET
De Delphi for .NET preview command-line compiler is te gebruiken als scripting taal binnen ASP.NET.
Dit betekent concreet dat we ook al bestaande Delphi code kunnen gebruiken als scripting code binnen ASP.NET pagina's.
Een klein voorbeeld betreft het converteren van temperatuur waarden, van Celsius naar Fahrenheit, wat door de volgende ASP.NET pagina (in Celsius.aspx) gedaan kan worden:
<html>
<head>
<title>Delphi for .NET en ASP.NET</title>
<script language="Delphi" runat="server">
procedure Celsius2FahrenheitClick(Sender: System.Object; E: EventArgs);
begin
edtFahrenheit.Text := Convert.ToString(9 / 5 *
Convert.ToDouble(edtCelsius.Text) + 32)
end;
procedure Fahrenheit2CelsiusClick(Sender: System.Object; E: EventArgs);
begin
edtCelsius.Text := Convert.ToString(5 / 9 *
(Convert.ToDouble(edtFahrenheit.Text) - 32))
end;
</script>
</head>
<body bgcolor="ffffcc">
<font face="verdana" size="2">
<form runat="server">
<br><b>Celsius:</b> <asp:textbox id="edtCelsius" runat="server"/>
<br><b>Fahrenheit:</b> <asp:textbox id="edtFahrenheit" runat="server"/>
<p>
<asp:button text="Celsius naar Fahrenheit"
OnClick="Celsius2FahrenheitClick" runat="server"/>
<asp:button text="Fahrenheit naar Celsius"
OnClick="Fahrenheit2CelsiusClick" runat="server"/>
</form>
</body>
</html>
De twee OnClick event handlers van de buttons bevatten hierbij gewoon Delphi code! Wie dit voorbeeld in praktijk wil zien werken, kan naar http://www.eBob42.com/cgi-bin/Celsius.aspx gaan waar het op het web uit te proberen is.
Code Behind
Nadeel van de code zoals we die in de eerste listing zagen is dat de HTML en de Delphi code in hetzelfde bestand staat (in mijn geval Celsius.aspx).
En het zou veel "netter" (en makkelijker te onderhouden) zijn als de code en de presentatie gescheiden is.
Dat kan met ASP.NET, en wordt ook wel Code Behind genoemd.
Als ik bovenstaand voorbeeld neem, zou dit in Code Behind vorm leiden tot twee nieuwe bestanden: Celsius2.aspx en Celsius2.pas.
Het Celsius2.aspx bestand zou er als volgt uit komen te zien (zonder één regel Delphi code):
<%@ Page language="Delphi" src="Celsius2.pas" Inherits="Celsius2.WebForm42" %> <html> <head> <title>Delphi for .NET en ASP.NET</title> </head> <body bgcolor="ffffcc"> <font face="verdana" size="2"> <form runat="server"> <br><b>Celsius:</b> <asp:textbox id="edtCelsius" runat="server"/> <br><b>Fahrenheit:</b> <asp:textbox id="edtFahrenheit" runat="server"/> <p> <asp:button id="btnCelsius2Fahrenheit" text="Celsius naar Fahrenheit" OnClick="Celsius2FahrenheitClick" runat="server"/> <asp:button id="btnFahrenheit2Celsius"text="Fahrenheit naar Celsius" OnClick="Fahrenheit2CelsiusClick" runat="server"/> </form> </body> </html>En de bijbehorende code - los van de user interface opmaak codes - zit dan in Celsius2.pas:
unit Celsius2; interface uses System.Web.UI, System.Web.UI.WebControls; type WebForm42 = class(System.Web.UI.Page) edtCelsius: TextBox; edtFahrenheit: TextBox; btnCelsius2Fahrenheit: Button; btnFahrenheit2Celsius: Button; protected procedure Celsius2FahrenheitClick(Sender: System.Object; E: EventArgs); procedure Fahrenheit2CelsiusClick(Sender: System.Object; E: EventArgs); end; implementation procedure WebForm42.Celsius2FahrenheitClick(Sender: System.Object; E: EventArgs); begin edtFahrenheit.Text := Convert.ToString(9 / 5 * Convert.ToDouble(edtCelsius.Text) + 32) end; procedure WebForm42.Fahrenheit2CelsiusClick(Sender: System.Object; E: EventArgs); begin edtCelsius.Text := Convert.ToString(5 / 9 * (Convert.ToDouble(edtFahrenheit.Text) - 32)) end; end.Helaas gaat dit nog niet goed met de Delphi for .NET preview command-line compiler. We krijgen een foutmelding die betrekking heeft of het koppelen van de OnClick event handlers aan de buttons (de Delphi code die achter de schermen gegenereerd wordt is niet correct). Als we C# als taal hadden gebruikt dan werkt het voorbeeld wel. Vervang hiertoe de eerste regel van Celsius2.aspx door:
<%@ Page language="C#" src="Celsius2.cs" Inherits="Celsius2.WebForm42" %>En gebruik de volgende C# code in Celsius2.cs om dit te demonstreren:
using System; using System.Web.UI; using System.Web.UI.WebControls; namespace Celsius2 { public class WebForm42: System.Web.UI.Page { public TextBox edtCelsius; public TextBox edtFahrenheit; public Button btnCelsius2Fahrenheit; public Button btnFahrenheit2Celsius; public void Celsius2FahrenheitClick(System.Object Sender, EventArgs E) { edtFahrenheit.Text = Convert.ToString(9.0 / 5.0 * Convert.ToDouble(edtCelsius.Text) + 32); } public void Fahrenheit2CelsiusClick(System.Object Sender, EventArgs E) { edtCelsius.Text = Convert.ToString(5.0 / 9.0 * (Convert.ToDouble(edtFahrenheit.Text) - 32)); } } }Dit probleem zou een show-stopper kunnen zijn voor ASP.NET en Code Behind met de preview van de Delphi for .NET command-line compiler (tot er weer een volgende update uitkomt), ware het niet dat er nog een manier is om de event handlers niet het Celsius2.aspx bestand aan te geven, maar dynamisch te koppelen.
Code Behind met AutoEventWireup
Het dynamisch koppelen van event handlers (achter de schermen dus) kunnen we doen in de Page_Load event handler, die echter pas wordt aangeroepen als de we AutoEventWireup optie in de eerste regel van het Celsius2.aspx bestand toevoegen.
De aangepaste Celsius2.aspx komt er dan als volgt uit te zien:
<%@ Page language="Delphi" src="Celsius2.pas" AutoEventWireup="true" Inherits="Celsius2.WebForm42" %> <html> <head> <title>Delphi for .NET en ASP.NET</title> </head> <body bgcolor="ffffcc"> <font face="verdana" size="2"> <form runat="server"> <br><b>Celsius:</b> <asp:textbox id="edtCelsius" runat="server"/> <br><b>Fahrenheit:</b> <asp:textbox id="edtFahrenheit" runat="server"/> <p> <asp:button id="btnCelsius2Fahrenheit" text="Celsius naar Fahrenheit" runat="server"/> <asp:button id="btnFahrenheit2Celsius" text="Fahrenheit naar Celsius" runat="server"/> </form> </body> </html>Merk op dat het nu verplicht is om de buttons een ID mee te geven, om zodoende de koppeling tussen een asp:button in het Celsius2.aspx bestand en de Delphi Button in het Celsius2.pas bestand tot stand te kunnen brengen. De AutoEventWireup zorgt ervoor dat de Page_Load event handler wordt aangeroepen, en daarbinnen kunnen we dan gebruik maken van de btnCelsius2Fahrenheit en btnFahrenheit2Celsius en bij allebei deze buttons een event handler aan hun OnClick toe te voegen via de Add_Click methode.
unit Celsius2; interface uses System.Web.UI, System.Web.UI.WebControls; type WebForm42 = class(System.Web.UI.Page) edtCelsius: TextBox; edtFahrenheit: TextBox; btnCelsius2Fahrenheit: Button; btnFahrenheit2Celsius: Button; protected procedure Celsius2FahrenheitClick(Sender: System.Object; E: EventArgs); procedure Fahrenheit2CelsiusClick(Sender: System.Object; E: EventArgs); public procedure Page_Load(Sender: System.Object; E: EventArgs); end; implementation procedure WebForm42.Page_Load(Sender: System.Object; E: EventArgs); begin btnCelsius2Fahrenheit.Add_Click(Self.Celsius2FahrenheitClick); btnFahrenheit2Celsius.Add_Click(Self.Fahrenheit2CelsiusClick) end; procedure WebForm42.Celsius2FahrenheitClick(Sender: System.Object; E: EventArgs); begin edtFahrenheit.Text := Convert.ToString(9 / 5 * Convert.ToDouble(edtCelsius.Text) + 32) end; procedure WebForm42.Fahrenheit2CelsiusClick(Sender: System.Object; E: EventArgs); begin edtCelsius.Text := Convert.ToString(5 / 9 * (Convert.ToDouble(edtFahrenheit.Text) - 32)) end; end.Deze combinatie - een .aspx bestand zonder event handlers maar met AutoEventWireup, en een .pas bestand waarin de Page_Load event handler wordt gebruikt om alle andere event handlers neer te zetten - werkt in ieder geval wel, en kan dus gebruikt worden om ook met de preview van de Delphi for .NET command-line compiler aan ASP.NET met Code Behind te doen.
Meer Informatie...
Voor de liefhebber zal ik tijdens mijn ASP.NET sessie op de CttM zal ik hier nog wat dieper op ingaan (en ook op de andere zaken die nog niet helemaal vlekkenloos werken, zoals het gebruik van een globals.axa bestand).
Daarnaast loont het de moeite om mijn eigen website (www.eBob42.com) in de gaten te houden alsmede de nieuwe SDGN website waar ik regelmatig met wat kleine artikeltjes voor aanvulingen zal zorgen (vooral als er weer nieuwe updates van de Delphi for .NET preview command-line compiler mochten verschijnen).
Mocht iemand nog vragen, opmerkingen of suggesties hebben, dan hoor ik die het liefst via .