Web services are services that operate on the Web and can be used by other applications. For example, when you want to display data from a data source on the Web in a Windows application, a Web service is a perfect solution, because the Windows application can call methods in the Web service to get that data. Web services are often used to implement multitiered, distributed data applications; I'll create a Web service here to do exactly that.
This example is called WebServ on the CD-ROM, and it'll read the authors table from the pubs database using SQL Server on a Web server. This service will implement two methods, GetAuthors and UpdateAuthors, to return a dataset holding the authors table and update that table in the data source, respectively. I'll use a Windows application to call these methods and display data.
The Web service here is the middle tier of our distributed data application, and although it does nothing more in this case than read and update the authors table, you can implement all kinds of logic in this tier, creating a business object that implements business rules. For example, your Web service could check if particular items are in stock, and omit any records for items that are currently not available.
To follow along, create a new Web service project now by selecting the File|New|Project menu item. This time, make sure that you select the ASP.NET Web Service icon in the Templates box of the New Project dialog, and give this project the name WebServ. This creates the new Web service project that you see in Figure 25.7.
The support file for the new Web service is Service1.asmx.vb, and the name of the new service is Service1. If you open Service1.asmx.vb in Visual Basic, you'll see that this new service is derived from the WebService class:
Imports System.Web.Services Public Class Service1 Inherits System.Web.Services.WebService ⋮
As with other Visual Basic projects, you can drag components into the new Web service at design time. To get access to the authors table, drag an OleDbDataAdapter object into the Web service, and use a data connection to connect the data adapter to the authors table on a server (see Chapter 20 for the details on how to do this; for example, see "Creating a New Data Connection" and "Data Access Using Data Adapter Controls" in that chapter). Next, use the Data|Generate Dataset menu item, which will create a new dataset class, DataSet1. This is the dataset class we'll use to access the authors table.
To expose methods from a Web service, you use the <WebMethod()> attribute. For example, to write the GetAuthors method, which returns a dataset filled with data from the authors table, add this code to Service1.asmx.vb now:
<WebMethod(Description:="Gets the authors")> _ Public Function GetAuthors() As DataSet1 Dim AuthorsTable As New DataSet1() OleDbDataAdapter1.Fill(AuthorsTable) Return AuthorsTable End Function
This new method, GetAuthors, will be available for other applications to call once they add a reference to our Web service. Similarly, we can add another method, UpdateAuthors, to update the authors table when we pass a dataset of changes to this method. Here's what that method looks like—note that to be safe, this method always returns a value, even if that value is Nothing:
<WebMethod(Description:="Updates the authors")> _ Public Function UpdateAuthors(ByVal _ _ Changes As DataSet1) As DataSet1 If (Changes Is Nothing) Then Return Nothing Else OleDbDataAdapter1.Update(Changes) Return Changes End If End Function
That completes the Web service. To build this Web service and make it available to other applications, select the Build|Build menu item now.
The next step is to create an application that will act as a user interface for the Web service. Add a Windows application project to the solution now by selecting the File|Add Project|New Project menu item. When the Add New Project dialog opens, select the Windows Application icon in the Templates box, name this new project WebServWindowsApplication, and click OK to open this new Windows application, as you see in Figure 25.8. Make this application the startup project by selecting the Project|Set as StartUp Project menu item.
The next step is to add a reference to our Web service to make the GetAuthors and UpdateAuthors methods available to us. To add that reference, right-click WebServWindowsApplication in the Solution Explorer and select the Add Web Reference item. This opens the Add Web Reference dialog, listing the available Web service directories. To add a Web reference to a Web service, you navigate to that service's DISCO or VSDISCO file. You can do that by entering the URL for that file directly in the Address box at the top of the Add Web Reference dialog (such as http://ServerName/WebServ/WebServ.vsdisco). Or, you can browse for the file you want on the server by clicking the link in the Add Web Reference dialog for the server you want to use; then, in the Available References box in that dialog, clicking the WebServ/WebServ.vsdisco entry. Either technique opens our Web service's entry in the Add Web Reference dialog, as you see in Figure 25.9. To add a reference to this Web service to our Windows application, click the Add Reference button.
Now that we have a reference to our Web service, we can use types defined in that Web service, such as DataSet1, and call the methods of that Web service, GetAuthors and UpdateAuthors. Let's see this in action. Add a data grid, DataGrid1, to the main form in our Windows application, WebServWindowsApplication, and two buttons with the captions "Get Data" and "Update Data" respectively.
Now drag a DataSet object from the Data tab of the toolbox onto the main Windows form, which will open the Add Dataset dialog you see in Figure 25.10. Make sure the Typed dataset option is selected, and select DataSet1 from the drop-down list. (In this example, I'm running the IIS Web server locally, so DataSet1 is given as WebServWindowsApplication.localhost.DataSet1 in Figure 25.10.) This creates a new dataset for us, DataSet11, which matches the type returned by our Web service, and which we can bind to the data grid.
To bind the data grid to our new dataset, select the data grid now and set its DataSource property to DataSet11, and its DataMember property to authors. The data grid is now bound to DataSet11, so we can fill that dataset with the Web service's GetAuthors method, and we'll do that when the "Get Data" button is clicked. The GetAuthors method returns a dataset, and the easiest way to fill DataSet11 with the data in that dataset is to use the DataSet11 object's Merge method. First, when the user clicks the "Get Data" button, we create an instance of our Web service, WebServ, so we can call that instance's methods:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim WebServ As New WebServWindowsApplication.localhost.Service1() ⋮ End Sub
Now we can use the methods in our Web service with the WebServ object. Here's how to fill the dataset DataSet11 from the Web service:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim WebServ As New WebServWindowsApplication.localhost.Service1() DataSet11.Merge(WebServ.GetAuthors()) End Sub
Using a Web service like this is cool—the Windows application connects to the Web service and calls Web service methods just as if they were part of a local component.
Similarly, if the user makes changes in the data in the data grid and clicks the "Update Data" button, we want to update the authors table with the new changes. To find those changes, we can use the GetChanges method of DataSet11 (as discussed in Chapter 21, as soon as the user makes changes in the bound data grid, those changes are immediately made to the dataset the data grid is bound to) to create a new dataset, Changes, which holds only the changed records:
Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click If DataSet11.HasChanges() Then Dim WebServ As New WebServWindowsApplication.localhost.Service1() Dim Changes As New WebServWindowsApplication.localhost.DataSet1() Changes.Merge(DataSet11.GetChanges()) ⋮ End If End Sub
And we can use the UpdateAuthors Web method to update the data source on the Web server, like this:
Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click If DataSet11.HasChanges() Then Dim WebServ As New WebServWindowsApplication.localhost.Service1() Dim Changes As New WebServWindowsApplication.localhost.DataSet1() Changes.Merge(DataSet11.GetChanges()) DataSet11.Merge(WebServ.UpdateAuthors(Changes)) End If End Sub
Note that I also merge the dataset UpdateAuthors returns with DataSet11 as we did when updating datasets in Chapter 23. (For example, the data provider may have added data to calculated fields, or updated primary key values, so it's a good idea to merge the returned dataset of changes with our main dataset.) And that's it—the example is ready to go. Run the example now and click the "Get Data" button, filling the data grid with data from the authors table via the Web service, as you see in Figure 25.11.
And that's it—our Web service works. Now we've created both Windows and Web services and put them to work. Next, it's time to take a look at how to deploy Visual Basic .NET applications.