创建测试页始终是访问 sql server 数据层并验证输入和输出参数是否得到正确处理的好办法。实际上,这是确保以后的生产解决方案中的 asp.net 页和组件能够按照预期方式工作的唯一办法。这对于从解决方案中的某个层调用其他层时的验证信任边界和安全性问题尤其正确。
另外,在进行测试时,请勿拘泥于创建生产类接口。您只需测试目标方法。实际上,故意创建一些您不愿以之为最终生产解决方案的“丑陋”测试页是一个好的策略!本文中,我创建了一些非常简单的 asp.net 页,其中包含一个测试记录列表和一个用于添加、编辑和删除测试记录的输入表单。
例如,以下是用于测试主题记录的 webform 布局。您会发现,它包含错误消息或其他消息的状态标签、记录计数标签、显示记录列表的数据网格、用于输入检索时使用的记录 id 的输入框以及支持添加、编辑和删除记录的小表格(参见图 10)。
图 10:用于测试主题记录的 webform 布局
在创建测试页时,最好使代码简洁明了。我通常会为每个按钮添加一小段代码,以调用本地方法来处理数据库操作。以下是 topictest.aspx 页上 get record(获取记录)按钮的代码。
private sub btngettopic_click(byval sender as system.object,byval e as system.eventargs) handles btngettopic.click try dim id as integer = int32.parse(txqueryid.text) getitem(id) ' 进行数据库调用 txid.text = txqueryid.text txtitle.text = mtitle txdescription.text = mdescription lbstatus.text = "success!" catch ex as exception lbstatus.text = ex.message end try end sub 请注意,本方法中实际执行的唯一操作是由 getitem(id) 方法调用处理的。它执行数据库调用并使用返回的值设置本地变量。以下是 getitem 方法的代码。请注意,它使用了大量的 sqlparameter 对象来处理输入和输出值。
private sub getitem(byval id as integer) try pr = new sqlparameter("return_value", sqldbtype.int) pr.direction = parameterdirection.returnvalue dim ptitle as sqlparameter = new sqlparameter with ptitle .direction = parameterdirection.output .dbtype = dbtype.string .parametername = "@title" .size = 30 end with dim pdescription as sqlparameter = new sqlparameter with pdescription .direction = parameterdirection.output .dbtype = dbtype.string .parametername = "@description" .size = 500 end with
cd = new sqlcommand
with cd .commandtext = "topicsgetitem" .commandtype = commandtype.storedprocedure .parameters.add(new sqlparameter("@admincode", "adm")) .parameters.add(new sqlparameter("@id", id)) .parameters.add(ptitle) .parameters.add(pdescription) .parameters.add(pr) .connection = cn .connection.open() .executenonquery() .connection.close() end with
' 检查返回代码 if not pr.value is nothing then select case int32.parse(pr.value) case 100 : throw new applicationexception("access violation") case 101 : throw new applicationexception("invalid id") end select end if ' 设置返回值 mtitle = ptitle.value.tostring() mdescription = pdescription.value.tostring() catch ex as exception throw new exception(ex.message, ex) end try end sub getitem 方法的另一个重要方面是使用了返回值参数。它在前几行代码中进行声明,并在执行存储过程后进行检查。请注意,我检查了已知错误代码 100 和 101。有关其他错误的处理方法,我们将在以后介绍如何创建成熟的中间层时进行介绍。问题在于,我要利用返回值并在需要时抛出一个自定义异常。
对于本解决方案示例,我最终生成了六个 web 表单,并用它们测试了将近 30 个存储过程和自定义函数。您可在本文开始部分列出的下载软件包中找到所有这些完成的表单。
现在我们已经定义了表、创建了存储过程和函数并生成了 asp.net web 表单,因此可以使用 visual studio .net 2003 生成数据库层的安装脚本了。数据库管理员(有时是您自己)可以将此脚本应用到生产服务器上。