Exposing Data Through a Web Service

for RuBoard

To expose data retrieved using ADO.NET with an XML Web Service, you can rely on the deep integration of Web services standards with the .NET Framework and VS .NET. This integration, coupled with the XML integration already present in ADO.NET, enables developers to expose ADO.NET through a Web service as simply as exposing it through any data access class.

The remainder of this section will provide a short overview of XML Web Services technology, followed by the steps you need to implement to use Web services with ADO.NET.

XML Web Services Technology

graphics/newterm.gif

Simply put, an XML Web Service provides a programmatic interface to the Web using standard XML grammars. The most notable of these interfaces are SOAP (Simple Object Access Protocol), which is used to specify the message format, and WSDL (Web Services Description Language, usually pronounced "wizz-dul"), which is used to describe the Web service. Both of these are controlled by the World Wide Web Consortium (W3C). For example, the .NET Framework supports the SOAP 1.1 specification, which you can find at http://www.w3.org/TR/2000/NOTE-SOAP-20000508/.

Note

For a more complete discussion of Web service protocols, see Chapter 11 of my book Building Distributed Applications with Visual Basic .NET (published by Sams) and the SOAP and WSDL specifications on the W3C Web site at www.w3c.org.


These standard protocols, along with HTTP, of course, provide a remote procedure call “like (RPC) communication model that is message based. Further, the ubiquity of HTTP and the wide adoption of XML and SOAP in the industry make the availability of Web services to any device and platform a reality. In this way, Web services eliminate many of the religious wars of the late 1990s over object technologies (such as COM/DCOM versus CORBA versus RMI) by providing an industry standard way of exposing functionality and consuming it. This approach means that a Web service is conceptually similar to a middle- tier component that exposes its methods as a "black box." However, Web services don't rely on proprietary component architectures ”instead, they use Internet standards that make them platform and language independent. These Web services then become the building blocks for application development as developers incorporate them into their applications to provide essential features.

In the long run, the low bar for entry and reliance on industry standards will free developers from having to use any specific language or toolset to create software that interoperates. For example, in the past, developers on the Windows platform built COM components and COM clients that could interoperate with each other using DCOM. However, this interoperation rarely, if ever, went beyond the developer's organization because of the limitations of DCOM and the absence of COM on any but the Windows platform. One of the key aspects of a Web service is that it abstracts the implementation of the application logic from the means used to communicate with it so that consumers of Web Services need only know where the service is located and the signatures of its methods. In this way, you can think of a Web service as simply another interface, albeit a programmatic one, to components you build with VB .NET.

In the short term , using a development tool that abstracts much of the heavy lifting required to build Web services, such as VS .NET, enables developers to remain highly productive and build Web services within their language of choice. With VS .NET, Microsoft is betting that as developers begin to adopt the Web service model, it will become the fundamental way in which devices (not just PCs, but also phones, PDAs, and a host of other Internet-enabled hardware) communicate. In addition, it will become as routine for applications to expose and consume Web services as it is today for applications to reuse components.

Building the Data Access Method

Because a Web service can be thought of as simply another interface to your data, you should strive to adhere to the multi-tier architecture discussed previously this week. In other words, you should create a data services tier that your Web services wrap to expose their data rather than writing data access code directly in the Web service itself. Taking this approach not only provides the layer of abstraction that makes maintenance and extensibility simpler, but also allows the data services code to be reused in ASP.NET pages as well.

For example, ComputeBooks might want to create a Web service that other public sites can call to retrieve a list of the top-selling books on the ComputeBooks site. This relationship is mutually beneficial. For example, a site that provides technical information for software developers is able to provide its users with information about what books (and therefore technologies) are currently hot, whereas ComputeBooks sees increased Web traffic resulting from the clickthroughs from the site using the Web service. Further, it's obvious that this information would also be useful to provide on ComputeBooks' own public site so that users browsing for books could see which books are popular. By abstracting the code required to retrieve the top-selling books into a method of a data access class (that returns a DataSet for example), it could be reused in both the Web service and ASP.NET page.

As a result, ComputeBooks first creates or adds a method to an existing data access class that queries the database to return the books. This class relies on a version of the ComputeBooksDABase class we discussed on Day 17, "ADO.NET in the Data Services Tier," that also incorporates support for the DataFactory class you learned about yesterday . Listing 19.1 shows the class definition and the TopSellers method.

Listing 19.1 Exposing top sellers. This class and method exposes the top five best- selling books for a specified time period.
 Imports ComputeBooks.Data Imports System.Collections.Specialized Public Class WebData : Inherits ComputeBooksDABase     Public Sub New(ByVal connect As String, ByVal provider As String)       MyBase.New(connect, provider)     End Sub     Public Function TopSellers(ByVal daysOut As Short) As DataSet       Dim ds As New DataSet("Catalog")       Dim parms As New HybridDictionary()       parms.Add("daysOut", daysOut)       Try         ds = MyBase.Factory.GetDataSet("Top5Sellers", parms)         ds.Tables(0).TableName = "TopSellers"         ds.Namespace = "www.computebooks.com"         ds.Prefix = "cbks"         Return ds       Catch e As Exception         MyBase.ThrowComputeBookException("TopSellers operation failed", e)       End Try     End Function End Class 
graphics/analysis.gif

In Listing 19.1, the WebData class includes a parameterized constructor that allows clients to pass in both the connection string and the provider to use. The base classes' constructor uses this information to initialize the instance of the DataFactory class that it uses internally.

You'll also notice that because the ComputeBooksDABase class exposes the DataFactory class as a protected property called Factory , it can be accessed in the TopSellers method using the MyBase ( base in C#) keyword. The GetDataSet method is then called and passed the statement name "Top5Sellers" . "Top5Sellers" encapsulates the stored procedure usp_Top5Sellers , which takes as its only parameter the number of days in the past to consider. For example, passing 30 into the TopSellers method, and thus into the stored procedure, returns the top five best-selling books over the past 30 days.

You'll also notice that the TableName property of the DataTable is populated to ensure that the XML is returned with the proper element names , along with Namespace and Prefix properties of the DataSet .

When the data services tier contains the method that the Web service will call, ComputeBooks can create the Web service to expose the data.

Building the Web Service

Within VS .NET, Web services are exposed in an ASP.NET Web Application or Web Service project as .asmx files. After opening or creating a project, you can click on the File menu or the project in the Solution Explorer and choose the Add New Item menu. This will invoke the Add New Item dialog from which you can choose Web Service to add the .asmx file with its associated code file to the project.

The methods of the Web service must be placed into a class (typically inherited from System.Web.Services.WebService ) that is defined in the associated code file.

Note

Although not required, by inheriting from WebService , the Web service class has access to the HTTP context information that includes the Session and Application state objects provided by ASP.NET.


graphics/newterm.gif

The default behavior is for VS .NET to create a code-behind file that has the same name as the .asmx file with the appropriate language extension (.cs or .vb). What makes this programming model really productive is the fact that the methods themselves are simply defined just as any other method in a class would be, with the exception that the method is marked with the WebMethod attribute from the System.Web.Services namespace. This attribute indicates that this method should be exposed through the Web service. In this way, the HTTP handler for the .asmx file does all the work by encapsulating the code required to listen for requests , parsing them, invoking the proper method, and sending results. The end result is that developers needn't work directly with SOAP or WSDL.

For example, ComputeBooks could create a Web service in C# called Catalog that exposes the GetTopSellers method. This is shown in Listing 19.2 (minus the Web services designer-generated code).

Listing 19.2 Creating the Web service method. This listing shows the code for the Web service that exposes the method used to return the top-selling books.
 using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Web; using System.Web.Services; using ComputeBooks.Data; using System.Configuration; namespace ComputeBooks.Web {        /// <summary>        /// ComputeBooks Catalog web service        /// </summary>        [WebService(Namespace="www.computebooks.com/catalog",        Description="ComputeBook's Catalog Web Service",        Name="ComputeBooksCatalog")]        public class Catalog : System.Web.Services.WebService        {          public Catalog()          {            InitializeComponent();          }          [WebMethod(Description="Retrieves the 5 top selling books",            EnableSession=false)]          public DataSet GetTopSellers(short daysOut)          {               DataSet books;               // Read the configuration information               string connect =                 ConfigurationSettings.AppSettings["SqlConnect"].ToString();               string provider =                 ConfigurationSettings.AppSettings["Provider"].ToString();               // Instantiate the data access class and call the method               WebData data = new WebData(connect,provider);               books = data.TopSellers(daysOut);               return books;          }        } } 
graphics/analysis.gif

What you should notice in Listing 19.2 is that the entire Web service is encapsulated in the Catalog class within the ComputeBooks.Web namespace. The only method it exposes through the service (the only one with the WebMethod attribute) is GetTopSellers . This method accepts the number of days in the past for which to base the calculation and passes this value to the TopSellers method of the data access class shown in Listing 19.1. However, before calling the method, the Web service is responsible for retrieving the connection string and .NET Data Provider to use. In this case, those values are specified in the Web.config file within the appSettings element like so:

 <?xml version="1.0" encoding="utf-8" ?> <configuration>   <appSettings>     <add key="SQLConnect" value="data source=ssosa;      initial catalog=ComputeBooks;user id=user;pooling=true" />     <add key="Provider" value="SqlClient" />   </appSettings> </configuration> 

These values are then passed to the constructor of the WebData class and subsequently to the DataFactory class before calling the TopSellers method. When the DataTable has been retrieved, it is simply returned from the Web service.

You'll also notice that the Description property is specified in both the WebMethod and WebService attributes to include the description of the Web service and the method to display to a user using the test harness page created by VS .NET. The WebService attribute also includes an explicit namespace declaration that will apply to all XML elements that directly pertain the Web service. In addition, the WebMethod attribute includes the EnableSession property that explicitly specifies that this method doesn't require the use of ASP.NET session state.

Note

All Web service methods do automatically have access to the Application object and therefore ASP.NET application state. However, to gain access to session state, the method must have the EnableSession property set to true .


After the Web service has been compiled, it can be navigated to and tested simply by calling the Catalog.asmx file, as shown in Figure 19.1.

Figure 19.1. Testing a Web service. This screenshot shows the test harness page dynamically created by ASP.NET that can be used to test the Web service. The window in the foreground is the result of testing the Web service using the Invoke button.

graphics/19fig01.jpg

You'll notice in Figure 19.1 that the test harness page shows the method, its description, and the arguments it exposes. After entering 30 in the daysOut parameter and pressing the Invoke button, the XML document in the foreground is produced. The interesting aspect of this document is that it contains the XSD schema along with the DataSet serialized to a DiffGram. In this way, the caller of the Web service automatically has the information necessary to validate and use the XML.

Note

graphics/newterm.gif

Actually, SOAP defines two ways that a Web service method, referred to as an operation, can be encoded in a request or response. The example here assumes the employment of document-style encoding (discussed in Section 5 of the SOAP specification) in which an XSD schema in the WSDL document is used to describe both the request and response. When using the document style, you can also specify how the parameters are to be encoded by explicitly using the SoapDocumentService attribute. Alternatively, you can use the SoapRpcMethod attribute on the Web method to specify the RPC encoding style in which parameters and return values are simply encoded using their names. However, if you use the RPC style, the Web service can't return objects such as the DataSet because no XSD schema will be generated. If you try to do so, an exception will be thrown.


for RuBoard


Sams Teach Yourself Ado. Net in 21 Days
Sams Teach Yourself ADO.NET in 21 Days
ISBN: 0672323869
EAN: 2147483647
Year: 2002
Pages: 158
Authors: Dan Fox

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net