Transmitting Complex Data in an XML Web Service


To this point, you have worked with only a simple Web service. The TemperatureService Web service returns only a single integer value. However, Web services can return more complex data types. In the following sections, you explore how to use a Web service with arrays, classes, DataSets , and binary files.

XML Web Services and Arrays

Imagine that you want to build a Web service that enables you to broadcast news items to Web sites. For example, you might want to build an ASP.NET news service that carries the latest news on programming with ASP.NET.

One way to implement the Web service would be to have the service return an array of news items. This way, you could transmit multiple news items at a time. The Web sites that receive your news broadcast could format individual news items in any way that they please .

The Web service in Listing 22.6 contains a single method named GetNews that returns an array.

Listing 22.6 NewsService.asmx
 <%@ WebService Class="NewsService" %> Imports System Imports System.Web.Services <WebService( Namespace:="http://yourdomain.com/webservices" )> _ Public Class NewsService : Inherits WebService <WebMethod( CacheDuration:=30 )>  Public Function GetNews() As String()   Dim arrNews( 2 ) As String   arrNews( 0 ) = "Visit superexpert.com for ASP.NET News!"   arrNews( 1 ) = "Visit AspWorkshops.com for ASP.NET Training!"   arrNews( 2 ) = "Visit superexpertControls.com for ASP.NET Controls!"   Return arrNews End Function End Class 

The C# version of this code can be found on the CD-ROM.

The Web service in Listing 22.6 returns a list of news items as a one-dimensional array of strings. Every time the GetNews method is invoked, all three items in the array are returned.

NOTE

The CacheDuration property is used with the GetNews method in Listing 22.6. This property is set to cache the results of the method in memory for 30 seconds. Making liberal use of the CacheDuration property is a good idea when the data returned from a Web service changes infrequently.


After you create the Web service in Listing 22.6, any Web sites that want to subscribe to your service can build proxy classes for it.

To create the proxy class, use the Wsdl.exe tool to create the source for the class file like this:

 
 wsdl /l:vb http://www.YourSite.com/newsService.asmx?WSDL 

Then compile the source for the proxy class as follows :

 
 vbc /t:library /r:System.dll,System.Web.Services.dll,System.XML.dll NewsService.vb 

Finally, you must copy the compiled proxy class, NewsService.dll , to the application's /bin directory.

After you create a proxy class for the NewsService Web service, you can use the class in an ASP.NET page. The page in Listing 22.7 illustrates how you can use the NewsService class to format and display news items.

Listing 22.7 DisplayNews.aspx
 <Script Runat="Server"> Sub Page_Load   Dim objNewsService As NewsService   Dim arrNews As String()   objNewsService = New NewsService()   arrNews = objNewsService.GetNews()   rptNews.DataSource = arrNews   rptNews.DataBind End Sub </Script> <html> <head><title>DisplayNews.aspx</title></head> <body> <h2>The lastest news:</h2> <asp:Repeater   ID="rptNews"   Runat="Server">   <ItemTemplate>   <li> <%# Container.DataItem %>   </ItemTemplate> </asp:Repeater> </body> </html> 

The C# version of this code can be found on the CD-ROM.

In Listing 22.7, an instance of the NewsService proxy class is created in the Page_Load subroutine. The GetNews() method retrieves a list of current news items. These news items are assigned to an array that is bound to a Repeater control, which formats each news item (see Figure 22.4).

Figure 22.4. The DisplayNews.aspx page.

graphics/22fig04.jpg

XML Web Services and Classes

You can pass a class that contains public properties and fields back and forth to a Web service. This capability is useful when you need to work with structured data.

In the preceding section, for example, you developed a Web service that returns a list of news items. Each news item was represented by a single string in an array. However, say you want to return multiple properties for each item. Instead of simply returning the text for each one, you might also want to return the date on which it was posted and a URL associated with it for retrieving additional information.

You can improve on the NewsService Web service by using an array of classes rather than an array of strings. Listing 22.8 contains the class definition for a NewsItem .

Listing 22.8 NewsItem.vb
 Namespace myComponents Public Class NewsItem   Public Headline As String   Public Posted As Date   Public URL As String End Class End Namespace 

The C# version of this code can be found on the CD-ROM.

Before you can use the NewsItem class in Listing 22.8, you'll need to compile it:

 
 vbc /t:library NewsItem.vb 

Next, you'll need to copy the compiled NewsItem.dll file to your application's /bin directory.

The page in Listing 22.9 contains the new and improved Web service.

Listing 22.9 BetterNewsService.asmx
 <%@ WebService Class="BetterNewsService" %> Imports System Imports System.Web.Services Imports myComponents <WebService( Namespace:="http://yourdomain.com/webservices" )> _ Public Class BetterNewsService : Inherits WebService <WebMethod( CacheDuration:=30 )> Public Function GetNews() As NewsItem()   Dim arrNews( 2 ) As NewsItem   arrNews( 0 ) = New NewsItem   arrNews( 0 ).Headline = "Visit superexpert.com for ASP.NET News!"   arrNews( 0 ).Posted = #12/12/2002#   arrNews( 0 ).URL = "http://www.superexpert.com"   arrNews( 1 ) = New NewsItem   arrNews( 1 ).Headline = "Visit ASPWorkshops for ASP.NET Training!"   arrNews( 1 ).Posted = #2/1/2002#   arrNews( 1 ).URL = "http://www.AspWorkshops.com"   arrNews( 2 ) = New NewsItem   arrNews( 2 ).Headline = "Visit superexpertControls.com for ASP.NET Controls!"   arrNews( 2 ).Posted = #2/14/2002#   arrNews( 2 ).URL = "http://www.superexpertControls.com"   Return arrNews End Function End Class 

The C# version of this code can be found on the CD-ROM.

In Listing 22.9, the namespace for the NewsItem class that you created in Listing 22.8 is imported with the Imports statement. When the GetNews method is invoked, the method returns an array of NewsItem objects. The three NewsItem objects are declared within the method.

After you create the Web service in Listing 22.9, you can build a proxy class that enables you to use the Web service in your applications. First, you need to generate the source code for the proxy class like this:

 
 Wsdl /l:vb http://www.YourSite.com/BetterNewsService.asmx?WSDL 

Next, you need to compile the proxy class as follows:

 
 vbc /t:library /r:System.dll,System.Web.Services.dll,System.XML.dll BetterNewsService.vb 

After you copy the compiled proxy class, BetterNewsService.dll , to your ASP.NET application's /bin directory, you can start using the class in your ASP.NET pages. The page in Listing 22.10 uses the proxy class to display a list of news items.

Listing 22.10 DisplayBetterNews.aspx
 <Script Runat="Server"> Sub Page_Load   Dim objNewsService As BetterNewsService   Dim arrNews As NewsItem()   objNewsService = New BetterNewsService()   arrNews = objNewsService.GetNews()   rptNews.DataSource = arrNews   rptNews.DataBind() End Sub </Script> <html> <head><title>DisplayBetterNews.aspx</title></head> <body> <h2>The lastest news:</h2> <asp:Repeater   ID="rptNews"   Runat="Server">   <itemTemplate>   <li> <%# Container.DataItem.Posted %>   <br> <%# Container.DataItem.Headline %>   <br> <%# Container.DataItem.URL %>   </itemTemplate> </asp:Repeater> </body> </html> 

The C# version of this code can be found on the CD-ROM.

In Listing 22.10, an instance of the BetterNewsService proxy class is initialized in the Page_Load subroutine. An array of NewsItem objects is created to contain the news items retrieved by the GetNews method. This array is bound to a Repeater control to format and display each news item (see Figure 22.5).

Figure 22.5. The DisplayBetterNews.aspx page.

graphics/22fig05.jpg

The NewsItem class is automatically created for you when you create the proxy class for the BetterNewsService . If you are curious , you can verify that the class was created by opening the BetterNewsService.vb file in Notepad. Because the class is created automatically for you, you don't have to worry about distributing the class definitions used with your Web service.

Web Services and DataSets

You can pass DataSets to and from a Web service when you need to work with sets of database records. For example, imagine that you are a product wholesaler and you want to distribute a list of your products to multiple retail Web sites. You can create a Web service method that returns a DataSet .

The Web service in Listing 22.11, for example, retrieves a list of products from the Products table in the Northwind database.

Listing 22.11 ProductsService.asmx
 <%@ WebService Class="ProductsService" %> Imports System Imports System.Web.Services Imports System.Data Imports System.Data.SqlClient <WebService( Namespace:="http://yourdomain.com/webservices" )> _ Public Class ProductsService : Inherits WebService <WebMethod()> Public Function GetProducts( CategoryName As String ) As DataSet   Dim strSelect As String   Dim conNorthwind As SQLConnection   Dim dadNorthwind As SQLDataAdapter   Dim dstProducts As DataSet   strSelect = "SELECT ProductName, UnitPrice, UnitsInStock, CategoryName " & _     "FROM Products, Categories WHERE Products.CategoryID = " & _     "Categories.CategoryID AND CategoryName = @CategoryName"   conNorthwind = New SQLConnection( "Server=localhost;UID=sa;PWD=secret; Database=Northwind" )   dadNorthwind = New SQLDataAdapter( strSelect, conNorthwind )   dadNorthwind.SelectCommand.Parameters.Add( "@CategoryName", CategoryName )   dstProducts = New DataSet   dadNorthwind.Fill( dstProducts, "Products" )   Return dstProducts End Function End Class 

The C# version of this code can be found on the CD-ROM.

In Listing 22.11, the GetProducts method accepts a single parameter: the name of a category. The method opens a connection to the Northwind database, retrieves a list of products that match the category name, and returns the results as a DataSet .

After you create the Web service, you can generate a proxy class for the service by executing the Wsdl.exe tool from the command line like this:

 
 Wsdl /l:vb http://www.SomeSite.com/ProductsService.asmx?WSDL 

Next, you need to compile the proxy class by executing the Visual Basic command-line compiler like this:

 
[View full width]
 
[View full width]
vbc /t:library /r:System.dll,System.Web.Services.dll,System.XML.dll, System.Data.dll graphics/ccc.gif ProductsService.vb

Finally, you need to copy the compiled proxy class, ProductsService.dll , to your ASP.NET application's /bin directory.

After you create the ProductsService proxy class, you can use it in an ASP.NET page. The page in Listing 22.12 retrieves a list of products from the ProductsService Web service.

Listing 22.12 DisplayProducts.aspx
 <Script Runat="Server"> Sub Page_Load   Dim objProductsService As ProductsService   objProductsService = New ProductsService()   dgrdProducts.DataSource = objProductsService.getProducts( "Seafood" )   dgrdProducts.DataBind() End Sub </Script> <html> <head><title>DisplayProducts.aspx</title></head> <body> <h2>Available Products:</h2> <asp:DataGrid   ID="dgrdProducts"   Runat="Server"/> </body> </html> 

The C# version of this code can be found on the CD-ROM.

In the Page_Load subroutine in Listing 22.12, an instance of the ProductsService proxy class is initialized. Next, the GetProducts method is called to retrieve a list of Seafood products. The DataSet returned by the method is bound to a DataGrid control and displayed (see Figure 22.6).

Figure 22.6. The DisplayProducts.aspx page.

graphics/22fig06.jpg

Web Services and Binary Files

You can pass and retrieve binary files to and from a Web service. For example, you could create a Web service that works with music files, program files, or images.

The Web service in Listing 22.13 generates an image from a string of text.

Listing 22.13 ImageService.asmx
 <%@ WebService Class="ImageService" %> Imports System Imports System.Web.Services Imports System.Drawing Imports System.Drawing.Imaging Imports System.IO <WebService( Namespace:="http://yourdomain.com/webservices" )> _ Public Class ImageService : Inherits WebService <WebMethod()> Public Function GetTextImage( strText As String ) As Byte()   Dim objBitmap As Bitmap   Dim objGraphics As Graphics   Dim objFont As Font   Dim strmBuffer As MemoryStream   objBitmap = New Bitmap( 300, 50 )   objGraphics = Graphics.FromImage( objBitmap )   objFont = New Font( "Impact", 24 )   objGraphics.DrawString( strText, objFont, Brushes.Red, 1, 1 )   strmBuffer = New MemoryStream()   objBitmap.Save( strmBuffer, ImageFormat.Gif )   Return strmBuffer.ToArray() End Function End Class 

The C# version of this code can be found on the CD-ROM.

The Web service in Listing 22.13 contains a method named GetTextImage . When you pass a string of text to this method, it generates an image that displays the text.

The image is represented by a bitmap. You cannot return a bitmap directly from a method in a Web service. In Listing 22.13, the bitmap is first converted into a byte array by using the ToArray method of the MemoryStream class. The Web method returns the byte array.

NOTE

When the image is retrieved from the Web service, the image is automatically Base64 encoded when sent across the wire and Base64 decoded when received. To avoid the overhead of Base64 encoding binary data with a Web service, you can take advantage of the Direct Internet Message Encapsulation (DIME) protocol. DIME enables you to attach binary data to a Web service in much the same way as you can attach a file to an email message. To learn more about DIME, search for Web Services Enhancements at the Microsoft MSDN Web site (http://msdn.microsoft.com).


Before you can use this Web service in an application, you must first create a proxy class. The first step is to generate the source for the class by using the Wsdl.exe tool like this:

 
 Wsdl /l:vb http://www.YourSite.com/ImageService.asmx?wsdl 

Next, you need to compile the proxy class like this:

 
 vbc /t:library /r:System.dll,System.Web.Services.dll,System.XML.dll ImageService.vb 

Finally, you need to copy the compiled proxy class, ImageService.dll , to the ASP.NET application's /bin directory.

After you create the proxy class, you can use it in an ASP.NET page. The page in Listing 22.14 displays the image generated by the Web service.

Listing 22.14 DisplayImage.aspx
 <%@ Page ContentType="image/gif" %> <%@ Import Namespace="System.Drawing" %> <%@ Import Namespace="System.Drawing.Imaging" %> <%@ Import Namespace="System.IO" %> <Script Runat="Server"> Sub Page_Load   Dim objImageService As ImageService   Dim objBitmap As Bitmap   Dim strmBuffer As MemoryStream   objImageService = New ImageService   strmBuffer = New MemoryStream( objImageService.GetTextImage( "Hello World!" ) )   objBitmap = New Bitmap( strmBuffer )   objBitmap.Save( Response.OutputStream, ImageFormat.Gif ) End Sub </Script> 

The C# version of this code can be found on the CD-ROM.

The first line in Listing 22.14 contains a page directive that sets the content type of the page. Because this page displays a GIF image, the ContentType attribute is set to the value image/gif .

An instance of the ImageService proxy class is created in the Page_Load subroutine. The GetTextImage method is called with the string Hello World! and it returns a byte array that represents the image returned by the Web service.

The byte array is converted into a memory stream by using the constructor for the MemoryStream class. Finally, a bitmap is created from the memory stream and saved to the output stream of the Response object. The end result is that the GIF image is displayed (see Figure 22.7).

Figure 22.7. The DisplayImage.aspx page.

graphics/22fig07.jpg



ASP.NET Unleashed
ASP.NET 4 Unleashed
ISBN: 0672331128
EAN: 2147483647
Year: 2003
Pages: 263

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