将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的预览示例,正式版本的结果也许不完全如此,当然也许就是如此。
新闻热点
疑难解答
图片精选