您创建的业务对象将在 Web 服务器上运行,提供分布式应用程序所需的性能和可伸缩性。另外,您将把业务对象实现为 XML Web services,这样客户端可以使用标准 Internet 协议从任何平台与您的业务对象进行通信。有关详细信息,请参见使用 XML Web services 进行 Web 编程。
在本演练中,XML Web services 组件将保存数据连接和数据集定义。然后将添加 XML Web services 方法以公开此数据集,这使其他应用程序能够查看和修改此数据集。
ASP.NET Web 服务项目模板是基于 Web 的项目,旨在创建将其自身的接口公开为 XML Web services 的中间层组件。有关更多信息,请参见 Visual Studio 中的 ASP.NET Web 服务项目。
XML Web services 将公开两个方法。第一个方法 GetAuthors 将从数据库返回数据集。第二个方法 UpdateAuthors 将用用户的更改更新数据库。创建了若干私有成员来实现这些方法。它们包括数据集定义、数据适配器、数据连接和若干从数据库中检索数据和更新数据库的命令对象。下面的关系图描述了 XML Web services。
分布式应用程序的中间层
提示 如果 Web 服务器位于您的计算机上,则可以使用服务器名称 LOCALHOST。
提示 如果在创建 ASP.NET Web 服务项目方面有困难,请参见“Web 访问失败”对话框。
在此组件中,您将创建与数据存储区的连接并通过数据集获取数据实例。
您将向 XML Web services 添加两个对象:一个 SqlDataAdapter 对象和一个 SqlConnection 对象。连接对象创建到数据库的新连接,而数据适配器则查询数据库并将结果发送到 DataSet 对象中。数据适配器还用用户对数据集所做的更改来更新数据库。通过使用这个到数据库的连接,将创建一个数据集来保存在数据库中存在的信息的实例。此数据集稍后将在本演练中用来显示 Windows 窗体和 Web 窗体页中的数据。有关概述,请参见分布式应用程序和数据集成介绍。
创建数据库连接和数据适配器
注意 默认情况下,服务器资源管理器在开发环境的左侧显示为一个垂直选项卡。如果看不到此选项卡,请单击“视图”菜单,然后选择“服务器资源管理器”。
注意 如果在您的系统上没有设置集成安全性,请与网络管理员联系。
一个新节点出现在服务器资源管理器的“数据连接”节点中。
注意 如果数据库连接失败,请与数据库管理员联系。
注意 本演练使用 SqlDataAdapter 对象,此对象已针对使用 SQL Server 7.0 或更高版本进行了优化。也可以使用 OleDbDataAdapter 对象,这是因为它更通用,并提供对任何与 OLE DB 兼容数据源的 ADO.NET 访问权。如果要连接的数据库不是 SQL Server 数据库,则项目系统会创建一个 OleDbDataAdapter 对象和一个 OleDbConnection 对象。
注意 在本演练中,已使用authors
表中的一些列和所有的行填充了数据集。在成品应用程序中,通常通过创建只返回所需列和行的查询来优化数据访问。有关示例,请参见演练:使用参数化查询在 Windows 窗体中显示数据。
需要配置项目的安全设置以便使用集成安全性。通过关闭匿名访问并打开模拟来执行此操作。有关更多信息,请参见安全模型。
配置集成 Windows 身份验证
若要为项目配置集成 Windows 身份验证,需要使用“Internet 信息服务”工具更改项目文件并配置项目。
<system.web>
标记后面的行中添加下面的标记,以便为 XML Web services 配置集成安全性。
Copy Co
<identity impers/>
创建数据集类定义
注意 将创建数据集架构文件 authors1.xsd 并将其添加到项目中。此架构文件包含 authors1 的类定义。该类(从 DataSet 类继承)包含 authors 表的类型化数据集定义。
本演练的下一步是从业务对象公开刚创建的数据集对象。此操作使数据集可供 Windows 或 Web 应用程序使用。
将方法添加到 XML Web services
如下所示,此方法创建一个新的 authors1 数据集,并根据 authors 表使用 SqlDataAdapter 对象填充该数据集。然后此方法返回数据集。
Copy Co
' Visual Basic<WebMethod> Public Function GetAuthors() As authors1 Dim authors As New authors1() SqlDataAdapter1.Fill(authors) Return authorsEnd Function// C#[WebMethod]public authors1 GetAuthors() { authors1 authors = new authors1(); sqlDataAdapter1.Fill(authors); return authors;}
如下所示,此方法有一个 authors1 数据集参数 (
authorChanges
),该参数包含已更改的数据并通过 SqlDataAdapter.Update 方法更新数据库。Update 方法接受数据集中的更改。数据集返回给客户端。客户端然后用这个返回的数据集更新它自己的 authors1 数据集实例。有关 Update 方法和如何接受数据集更改的信息,请参见数据适配器介绍。
Copy Co
' Visual Basic<WebMethod> Public Function UpdateAuthors(ByVal authorChanges _As authors1) As authors1 If Not (authorChanges Is Nothing) Then SqlDataAdapter1.Update(authorChanges) Return authorChanges Else Return Nothing End IfEnd Function// C#[WebMethod]public authors1 UpdateAuthors(authors1 authorChanges){ if (authorChanges != null) { sqlDataAdapter1.Update(authorChanges); return authorChanges; } else { return null; }}
注意 在成品应用程序中,将向这些方法添加错误检查和异常处理功能。
在上一节中,您创建了一个中间层业务对象,该对象包含绑定到 SQL Server 数据库的数据集。您向中间层 AuthorsWebService XML Web services 中添加了代码,以便从数据源获取数据并用更改更新数据源。客户端通过 GetAuthors 和 UpdateAuthors XML Web services 方法访问这些函数。
创建了用于数据访问的中间层业务对象并将其公开为 XML Web services 后,下一步是创建客户端界面。本演练中有两个方案:传统的 Windows 窗体和 Web 窗体页。两个方案在此示例中被创建为同一解决方案中的不同项目。
Windows 界面使用客户机的功能来处理部分应用程序处理工作。通常,Windows 界面比基于 Web 的界面提供更完善的功能和更丰富的用户操作。服务器上的负载比 Web 前端的负载少,这是因为服务器不必执行所有的应用程序逻辑。另外,Windows 界面可以利用通过操作系统可用的资源,包括对文件系统和注册表的调用。
下列关系图突出显示要实现的客户端。
分布式应用程序中的 Windows 客户端
Windows 应用程序(由一个窗体 Windows 窗体组成)将包含一个对 AuthorsWebService 的 Web 引用。单击窗体上的“Load”(加载)按钮时,数据库中的数据将显示在 DataGrid 控件中。这一加载行为是通过调用 XML Web services 的 GetAuthors 方法实现的。DataGrid 控件允许直接编辑,并将数据更改直接传递到基础数据集。此窗体还会有一个“Save”(保存)按钮。此按钮的代码将调用 XML Web services 的 UpdateAuthors 方法,以便将更改保存回数据库。
创建 Windows 应用程序
AuthorsWinClient 项目随即添加到解决方案中。Form1 自动添加到项目中并且出现在 Windows 窗体设计器中。
authors1
数据集的实例。
将控件添加到窗体
为 LoadData 和 SaveData 按钮添加代码
AuthorData
数据集合并,XML Web services 的 Credentials 属性用于将您的身份传递给 XML Web services,该服务接着将它传递给数据库服务器。将如下所示的代码添加到方法中。
注意 如果 XML Web services 不是在本地计算机上运行的,则需要用运行 XML Web services 的服务器名称替换代码示例中的localhost
。
Copy Co
' Visual BasicPrivate Sub LoadData_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles LoadData.Click Dim ws As New AuthorsWinClient.localhost.AuthorsService() ws.Credentials = System.Net.CredentialCache.DefaultCredentials AuthorData.Merge(ws.GetAuthors())End Sub// C#private void LoadData_Click(object sender, System.EventArgs e){ AuthorsWinClient.localhost.AuthorsService ws = new AuthorsWinClient.localhost.AuthorsService(); ws.Credentials = System.Net.CredentialCache.DefaultCredentials; AuthorData.Merge(ws.GetAuthors());}
如果数据集有改动,则将创建一个 authors1 类型的新数据集来仅保存更改的数据。然后,此数据集被传递到 XML Web services 的
UpdateAuthors
方法。此数据集与接受的更改一起返回,并且更新
AuthorData
数据集以反映这些新的更改。有关接受数据集更改的更多信息,请参见数据适配器介绍。
注意 在成品应用程序中,将需要在这一步中考虑数据并发问题。有关更多信息,请参见介绍 ADO.NET 中的数据并发。
将以下代码添加到方法中:
Copy Co
' Visual BasicPrivate Sub SaveData_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles SaveData.Click If AuthorData.HasChanges() Then Dim ws As New AuthorsWinClient.localhost.AuthorsService() ws.Credentials = System.Net.CredentialCache.DefaultCredentials Dim diffAuthors As New AuthorsWinClient.localhost.authors1() diffAuthors.Merge(AuthorData.GetChanges()) diffAuthors = ws.UpdateAuthors(diffAuthors) AuthorData.Merge(diffAuthors) End IfEnd Sub// C#private void SaveData_Click(object sender, System.EventArgs e){ if (AuthorData.HasChanges()) { AuthorsWinClient.localhost.AuthorsService ws = new AuthorsWinClient.localhost.AuthorsService(); ws.Credentials = System.Net.CredentialCache.DefaultCredentials; AuthorsWinClient.localhost.authors1 diffAuthors = new AuthorsWinClient.localhost.authors1(); diffAuthors.Merge(AuthorData.GetChanges()); diffAuthors = ws.UpdateAuthors(diffAuthors); AuthorData.Merge(diffAuthors); }}
运行应用程序
显示出一个窗口,其中包含一个空表,表的标头来自 pubs 数据库中的 authors 表。
Save
保存所做的更改。
在上一节中,您在解决方案中添加了一个 Windows 窗体项目作为 Windows 界面。将 Windows 窗体连接到了在第一节中创建的 XML Web services,并使用 DataGrid 和 Button 控件创建了用于加载和更新数据的用户界面。在下一节中,您将为解决方案创建基于 Web 的用户界面。
Web 界面有助于应用程序访问各种不同的客户机和浏览器。所有用户界面处理都在 Web 服务器上而不是在客户端完成。您将使用 Web 窗体页来创建一个 Web 界面,与上一节中创建的 Windows 界面一样,此界面访问同一个中间层业务对象。下列关系图突出显示要实现的客户端。
分布式应用程序中的 Web 客户端
创建 Web 窗体应用程序
新项目添加到解决方案资源管理器。一个名为 WebForm1.aspx 的 Web 窗体页添加到项目中并加载到设计器中。
将控件添加到 Web 页
为“编辑”、“更新”和“取消”按钮添加代码
AuthorData
数据集,并将此数据集绑定到 DataGrid 控件。每当页在往返过程后返回用户时,网格都将包含来自数据库中数据的全新副本。XML Web services 的 Credentials 属性用于将您的身份传递给 XML Web services,该服务接着将它传递给数据库服务器。
注意 在本演练中,每当 Web 窗体页下载到客户端浏览器时,都会从数据库中检索 authors 表的新副本。这可能不能提供最佳性能。有关优化性能的其他方法的讨论,请参见 Web 数据访问策略建议。
Copy Co
' Visual BasicPrivate Sub Page_Load(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles MyBase.Load Dim ws As New AuthorsWebClient.localhost.AuthorsService() ws.Credentials = System.Net.CredentialCache.DefaultCredentials AuthorData.Merge(ws.GetAuthors()) If Not Page.IsPostBack Then Me.DataGrid1.DataBind() End IfEnd Sub// C#private void Page_Load(object sender, System.EventArgs e){ AuthorsWebClient.localhost.AuthorsService ws = new AuthorsWebClient.localhost.AuthorsService(); ws.Credentials = System.Net.CredentialCache.DefaultCredentials; AuthorData.Merge(ws.GetAuthors()); if (! Page.IsPostBack) { DataGrid1.DataBind(); }}
在 Visual Basic 中,右击页并选择“查看代码”。在代码编辑器的左下拉框中选择 DataGrid1。在右下拉框中选择“EditCommand”。
- 或 -
在 Visual C# 中,单击 DataGrid1 控件。在“属性”窗口中,单击“事件”按钮以显示 DataGrid 事件的列表。双击 EditCommand 事件。
Copy Co
' Visual BasicPrivate Sub DataGrid1_EditCommand(ByVal source As Object, _ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _Handles DataGrid1.EditCommand DataGrid1.EditItemIndex = e.Item.ItemIndex DataGrid1.DataBind()End Sub// C#private void DataGrid1_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e){ DataGrid1.EditItemIndex = e.Item.ItemIndex; DataGrid1.DataBind();}
当用户单击“取消”按钮时,将引发 DataGrid 控件的 CancelCommand 事件。使用此事件将 EditItemIndex 属性设置为 -1,以便将当前行再次显示为文本。如下所示添加代码。
Copy Co
' Visual BasicPrivate Sub DataGrid1_CancelCommand(ByVal source As Object, _ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _Handles DataGrid1.CancelCommand DataGrid1.EditItemIndex = -1 DataGrid1.DataBind()End Sub// C#private void DataGrid1_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e){ DataGrid1.EditItemIndex = -1; DataGrid1.DataBind();}
AuthorData
数据集,并通过 XML Web services 将这些更改传递回数据库。为 UpdateCommand 事件创建事件处理程序。(有关添加事件处理程序的信息,请参见第 2 步。)如下所示添加代码。
Copy Co
' Visual BasicPrivate Sub DataGrid1_UpdateCommand(ByVal source As Object, _ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _Handles DataGrid1.UpdateCommand ' update each of the fields in the dataset row Dim i As Integer For i = 1 To AuthorData.authors.Columns.Count ' Controls(0) returns a Control object, so it must be cast ' to TextBox. Dim t As TextBox = CType(e.Item.Cells(i).Controls(0), TextBox) Dim row As DataRow = AuthorData.authors(e.Item.DataSetIndex) row(AuthorData.authors.Columns(i - 1).Caption) = t.Text Next ' Update the database. If Me.AuthorData.HasChanges() Then Dim ws As New AuthorsWebClient.localhost.AuthorsService() ws.Credentials = System.Net.CredentialCache.DefaultCredentials Dim diffAuthors As New AuthorsWebClient.localhost.authors1() diffAuthors.Merge(Me.AuthorData.GetChanges()) ws.UpdateAuthors(diffAuthors) AuthorData.Merge(diffAuthors) End If ' Take the row out of edit mode and display the new da
需要配置项目的安全设置以便使用集成安全性。通过关闭匿名访问并打开模拟来执行此操作。有关更多信息,请参见安全模型。
配置集成 Windows 身份验证
若要为项目配置集成 Windows 身份验证,需要使用“Internet 信息服务”工具更改项目文件并配置项目。
<system.web>
标记后面的行中添加下面的标记,以便为 XML Web services 配置集成安全性。
Copy Co
<identity impers/>
运行应用程序
在本节中,您在解决方案中添加了一个 ASP.NET Web 应用程序项目作为数据的浏览器界面。将 Web 窗体页连接到了在第一节中创建的 XML Web services,并使用了 DataGrid 控件创建用于显示和编辑数据的用户界面。
这时,您可以部署应用程序;如果需要,还可以添加程序的其他功能。下面给出几条建议。
您可以向服务器部署 Web 应用程序,也可以创建 Windows 应用程序的安装项目。有关部署 Web 应用程序的信息,请参见演练:部署 Web 解决方案。有关部署 Windows 应用程序的信息,请参见演练:部署 Windows 应用程序。
本演练处理 Intranet Web 应用程序的身份验证问题。您的应用程序可能被 Internet 上的用户访问,因此需要另一种身份验证解决方案。有关更多信息,请参见 IIS 身份验证和 Web 应用程序的访问权限。
本演练仅支持显示和更新数据库记录,而您可能还需要支持添加和删除记录。添加和删除不是 DataGrid Web 服务器控件支持的固有功能,但它们在 Windows 窗体 DataGrid 控件中受支持。有关更多信息,请参见允许用户删除 DataGrid Web 服务器控件中的项和在数据集中更新、插入和删除记录。
本演练使用集成 Windows 身份验证来控制数据库访问。数据库安全性只是 Web 应用程序需要注意的一个方面。有关 Web 应用程序安全性的讨论,请参见 Web 应用程序的基本安全实施策略。