將delphi視為腳本語言
支持asp.net的第一件事是讓asp.net將delphi視為腳本語言,讓asp.net能夠為各種asp文件類型調用delphi的.net編譯器。
asp.net要在iis虛路徑的根目錄下尋找web.config文件。下面是asp.net中使用delphi作腳本語言的web.config配制文件內容:
<configuration>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="delphiprovider" />
</assemblies>
<compilers>
<compiler language="delphi" extension=".pas"
type="borland.delphi.delphicodeprovider,delphiprovider" />
</compilers>
</compilation>
</system.web>
</configuration>
關于web配制文件的詳情請參msdn:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconformatofconfigurationfiles.asp
在我的機器(win2k pro)上測試delphi對asp.net的支持。要增加一個虛路徑來安放delphi腳本,我把這個路徑名定為"vslive"。
在我的機器配制文件上作了這個小改動后就可以來看asp.net是如何將delphi視為腳本語言的。
在asp.net中使用delphi代碼
首先編寫一個簡單應用來確認我們的delphi支持配制是正確的。下面是editdemo.aspx文件的代碼,有一個文本輸入框,一個按鈕。按鈕事件觸發顯示輸入框內容。
<html>
<script language="delphi" runat="server">
procedure buttonclick(sender: system.object; e: eventargs);
begin
message.text := edit1.text;
end;
</script>
<body>
<form runat="server">
<asp:textbox id="edit1" runat="server"/>
<asp:button text="click me!" onclick="buttonclick" runat="server"/>
</form>
<p><b><asp:label id="message" runat="server"/></b></p>
</body>
</html>
可以看到,asp按鈕對象的onclick事件觸發delphi的buttonclick過程,而delphi程序里卻使用了asp對象label message和text box edit1。雖然在delphi過程中沒有定義asp的二個變量,delphi代碼卻能找到它們。這是因為腳本中含有的delphi服務模塊能夠產生相應的delphi代碼。
現在可以用本地瀏覽器來瀏覽這個網頁了。因為我把腳本放在"vslive"虛路徑,所以打開:
http://localhost/vslive/editdemo.aspx.
以下是編譯之后形成的delphi代碼,代碼產生webform:
//------------------------------------------------------------------------------
// <autogenerated>
// 本代碼由一個工具生成
// 運行版本:1.0.3705.209
//
// 修改本文件將導致異常行為并丟失生成的代碼。
// </autogenerated>
//------------------------------------------------------------------------------
unit asp;
interface
uses system.collections, system.collections.specialized, system.configuration,
system.text, system.text.regularexpressions, system.web, system.web.caching,
system.web.sessionstate, system.web.security, system.web.ui, system.web.ui.webcontrols,
system.web.ui.htmlcontrols, system.globalization;
var
editdemo_aspx___autohandlers: integer;
editdemo_aspx___intialized: boolean = false;
editdemo_aspx___filedependencies: system.collections.arraylist;
type
editdemo_aspx = class(system.web.ui.page, system.web.sessionstate.irequiressessionstate)
protected
edit1: system.web.ui.webcontrols.textbox;
__control3: system.web.ui.webcontrols.button;
__control2: system.web.ui.htmlcontrols.htmlform;
message: system.web.ui.webcontrols.label;
procedure buttonclick(sender: system.object; e: eventargs);
public
constructor create;
function get_autohandlers: integer; override;
function get_applicationinstance: system.web.httpapplication; virtual;
function get_templatesourcedirectory: system.string; override;
procedure set_autohandlers(value: integer); override;
protected
property autohandlers: integer read get_autohandlers write set_autohandlers;
property applicationinstance: system.web.httpapplication read get_applicationinstance;
public
property templatesourcedirectory: system.string read get_templatesourcedirectory;
private
function __buildcontroledit1: system.web.ui.control;
function __buildcontrol__control3: system.web.ui.control;
function __buildcontrol__control2: system.web.ui.control;
function __buildcontrolmessage: system.web.ui.control;
procedure __buildcontroltree(__ctrl: system.web.ui.control);
protected
procedure frameworkinitialize; override;
public
function gettypehashcode: integer; override;
end;
implementation
procedure editdemo_aspx.buttonclick(sender: system.object; e: eventargs);
begin
message.text := edit1.text;
end;
constructor editdemo_aspx.create;
var
dependencies: system.collections.arraylist;
begin
inherited create;
if (asp.editdemo_aspx___intialized = false) then
begin
dependencies := system.collections.arraylist.create;
dependencies.add('d:/vslive/editdemo.aspx');
asp.editdemo_aspx___filedependencies := dependencies;
asp.editdemo_aspx___intialized := true;
end;
self.server.scripttimeout := 30000000;
end;
function editdemo_aspx.get_autohandlers: integer;
begin
result := asp.editdemo_aspx___autohandlers;
end;
function editdemo_aspx.get_applicationinstance: system.web.httpapplication;
begin
result := self.context.applicationinstance as system.web.httpapplication;
end;
function editdemo_aspx.get_templatesourcedirectory: system.string;
begin
result := '/vslive';
end;
procedure editdemo_aspx.set_autohandlers(value: integer);
begin
asp.editdemo_aspx___autohandlers := value;
end;
function editdemo_aspx.__buildcontroledit1: system.web.ui.control;
var
__ctrl: system.web.ui.webcontrols.textbox;
begin
__ctrl := system.web.ui.webcontrols.textbox.create;
self.edit1 := __ctrl;
__ctrl.id := 'edit1';
__ctrl.width := system.web.ui.webcontrols.unit.parse('300px', system.globalization.cultureinfo.invariantculture);
result := __ctrl;
end;
function editdemo_aspx.__buildcontrol__control3: system.web.ui.control;
var
__ctrl: system.web.ui.webcontrols.button;
begin
__ctrl := system.web.ui.webcontrols.button.create;
self.__control3 := __ctrl;
__ctrl.text := 'click me!';
__ctrl.add_click(self.buttonclick);
result := __ctrl;
end;
function editdemo_aspx.__buildcontrol__control2: system.web.ui.control;
var
__parser: system.web.ui.iparseraccessor;
__ctrl: system.web.ui.htmlcontrols.htmlform;
begin
__ctrl := system.web.ui.htmlcontrols.htmlform.create;
self.__control2 := __ctrl;
__parser := __ctrl as system.web.ui.iparseraccessor;
__parser.addparsedsubobject(system.web.ui.literalcontrol.create(''#13#10' '));
self.__buildcontroledit1;
__parser.addparsedsubobject(self.edit1);
__parser.addparsedsubobject(system.web.ui.literalcontrol.create(''#13#10' '));
self.__buildcontrol__control3;
__parser.addparsedsubobject(self.__control3);
__parser.addparsedsubobject(system.web.ui.literalcontrol.create(''#13#10' '));
result := __ctrl;
end;
function editdemo_aspx.__buildcontrolmessage: system.web.ui.control;
var
__ctrl: system.web.ui.webcontrols.label;
begin
__ctrl := system.web.ui.webcontrols.label.create;
self.message := __ctrl;
__ctrl.id := 'message';
result := __ctrl;
end;
procedure editdemo_aspx.__buildcontroltree(__ctrl: system.web.ui.control);
var
__parser: system.web.ui.iparseraccessor;
begin
__parser := __ctrl as system.web.ui.iparseraccessor;
__parser.addparsedsubobject(system.web.ui.literalcontrol.create('<html>'#13#10' '));
__parser.addparsedsubobject(system.web.ui.literalcontrol.create(''#13#10' <body>'#13#10' '));
self.__buildcontrol__control2;
__parser.addparsedsubobject(self.__control2);
__parser.addparsedsubobject(system.web.ui.literalcontrol.create(''#13#10' <p><b>'));
self.__buildcontrolmessage;
__parser.addparsedsubobject(self.message);
__parser.addparsedsubobject(system.web.ui.literalcontrol.create('</b></p>'#13#10' </body>'#13#10'</html>'#13#10));
end;
procedure editdemo_aspx.frameworkinitialize;
begin
self.__buildcontroltree(self);
self.filedependencies := asp.editdemo_aspx___filedependencies;
self.enableviewstatemac := true;
end;
function editdemo_aspx.gettypehashcode: integer;
begin
result := -764444463;
end;
end.
注意:這里介紹的是delphi的.net編譯器功能的預覽。正式發布的delphi 7生成的代碼與上面將有顯著不同。本文僅是示例說明如何在asp.net中使用delphi及其功能。
更高技術的網頁
asp.net的一些控件遠比html控件要更加智能化。其中之一就是日歷(calendar)控件。
以下代碼是calendar.aspx中的一部分。代碼提供二種方法讓控件設置日期:
瀏覽日歷然后選擇日期;
按照日期格式輸入日期,確認選擇。這種方法由.net的convert類支持。
<script language="delphi" runat="server">
procedure calendar1selected(sender: system.object; e: eventargs);
begin
label1.text := 'delphi for .net says you picked ' + calendar1.selecteddate.tostring('d');
end;
procedure button1click(sender: system.object; e:eventargs);
begin
calendar1.visibledate := system.convert.todatetime(edit1.text);
label1.text := 'delphi for .net says you set ' + calendar1.visibledate.tostring('d');
end;
</script>
<body >
<form runat="server">
<center>
<h1>delphi for .net running in asp.net</h1>
<p>please pick a date</p>
<asp:calendar id="calendar1" runat="server" forecolor="#0000ff" backcolor="#ffffcc"
onselectionchanged="calendar1selected">
<todaydaystyle font-bold="true"/>
<nextprevstyle forecolor="#ffffcc"/>
<dayheaderstyle backcolor="#ffcc66"/>
<selecteddaystyle forecolor="black" backcolor="#ccccff"/>
<titlestyle font-size="14pt" font-bold="true" forecolor="#ffffcc" backcolor="#990000"/>
<othermonthdaystyle forecolor="#cc9966"/>
</asp:calendar>
<p><asp:textbox id="edit1" width=200 runat="server"/>
<asp:button text="set date" id="button1" onclick="button1click" runat="server" />
</p>
<p><asp:label id="label1" runat="server"/></p>
</center>
</form>
</body>
在日歷上選擇日期觸發onselectionchanged事件,調用delphi的calendar1selected()過程。
輸入日期,點擊"set data"按鈕觸發button1click事件,調用delphi的button1click()過程。
數據處理
現在通過日歷的日期選擇來選擇顯示數據庫數據。在這個asp.net delphi網頁上,增加一個datagrid和一個textbox,前者顯示數據庫數據,后者輸入要顯示的數據庫域。
<%@import namespace="system.data"%>
<%@import namespace="system.data.sqlclient"%>
<script language="delphi" runat="server">
const
prodname = 'delphi for .net';
dispfields = 'orderid, customerid, shipname, shipcity, shipcountry';
procedure dateselected(sender: system.object; e: eventargs);
begin
label1.text := prodname + ' says you picked ' + calendar1.selecteddate.tostring('d');
datagrid1.datasource := getorders(calendar1.selecteddate);
datagrid1.databind;
end;
procedure button1click(sender: system.object; e:eventargs);
begin
calendar1.visibledate := system.convert.todatetime(edit1.text);
label1.text := prodname + ' says you set ' + calendar1.visibledate.tostring('d');
end;
procedure button2click(sender: system.object; e:eventargs);
begin
displayfields.text := dispfields;
end;
function getorders(date : datetime) : dataset;
var
adapter : sqldataadapter;
begin
adapter := sqldataadapter.create(
'select ' + displayfields.text + ' from orders '+
'where orderdate = ''' + date.tostring('d')+'''',
'server=(local);database=northwind;trusted_connection=yes');
result := dataset.create;
adapter.fill(result);
end;
</script>
<body >
<form runat="server">
<h1><%=prodname %> with a calendar, datagrid, & sqlclient in asp.net</h1>
<table>
<tr valign="top"><td>
<p><b>pick a date</b></p>
<asp:calendar id="calendar1" runat="server" forecolor="#0000ff" backcolor="#ffffcc"
onselectionchanged="dateselected">
<todaydaystyle font-bold="true"/>
<nextprevstyle forecolor="#ffffcc"/>
<dayheaderstyle backcolor="#ffcc66"/>
<selecteddaystyle forecolor="black" backcolor="#ccccff"/>
<titlestyle font-size="14pt" font-bold="true" forecolor="#ffffcc" backcolor="#990000"/>
<othermonthdaystyle forecolor="#cc9966"/>
</asp:calendar>
<p><asp:textbox id="edit1" width=150 runat="server"/>
<asp:button text="set date" id="button1" onclick="button1click" runat="server" />
</p>
</td><td valign="top">
<p><b>display fields:</b> <asp:textbox id="displayfields"
text="orderid, customerid, shipname, shipcity, shipcountry" width=500 runat="server"/>
<asp:button text="reset fields" id="button2" onclick="button2click" runat="server" /></p>
<asp:datagrid id="datagrid1" runat="server" bordercolor="#ffcc66" forecolor="#0000ff">
<headerstyle forecolor="#ffffcc" backcolor="#990000"/>
</asp:datagrid>
</td></tr></table>
<p><asp:label id="label1" runat="server"/></p>
</form>
</body>
每當用戶點擊日歷選擇日期時,就觸發onselectionchanged事件,調用dateselected()函數。
在getorders函數中,數據庫的連接由命名空間定義的sqlclient實現,數據庫是ms sql 2000的示范庫northwind。sqldataadapter將查詢結果安裝到datagrid中,顯示出數據表格,如附圖。
改變域輸入框的域名,再點擊日歷,就得到不同的結果。
這就是日歷驅動的數據庫查詢系統,由delphi for .net與asp.net共同完成。
結語
本文試圖簡略說明在asp.net中應用delphi是如何方便。
請記住,本文示例是delphi 7的預覽示例,正式版本的結果也許不完全如此,當然也許就是如此。
新聞熱點
疑難解答
圖片精選