Consuming a Web Service That Uses a DataSet


Consuming a Web Service That Uses a DataSet

Thus far, our XML Web service has returned custom data structures. The .NET Compact Framework provides the ability to transfer even more complex data, such as the DataSet . Although the .NET Compact Framework does not support a typed DataSet , we will see that you can work around this by using a regular DataSet .

Sending and receiving a regular DataSet is done exactly like sending a custom data structure or a simple piece of data, such as a string. The Web method simply needs to accept or return a System.Data.DataSet object. In our first DataSet aware XML Web service, we send the complete Quotes table down to the client. This would allow the application to go offline and still be able to display quotes when the user presses GetQuote .

There is a stored procedure in the QuotableQuotes database called GetQuotes that returns every quote in the Quotes table. Go back to the XML Web service designer, and drag this procedure onto the designer. Rename the new command to cmdGetQuotes . We will expose the Web method GetQuotes on the QuoteService that will return a DataSet to the caller. The DataSet will be filled by using the SqlDataAdapter in conjunction with the cmdGetQuotes SqlCommand object we just added to the project. The following is the code:

 
 C# [WebMethod] public DataSet GetQuotes() {   quoteConnection.Open();   try   {     DataSet quotesDS = new DataSet();     SqlDataAdapter quotesDa = new SqlDataAdapter(this.cmdGetQuotes);     quotesDa.Fill(quotesDS);     return quotesDS;   }   finally   {     quoteConnection.Close();   } } VB Public Function GetQuotes() As DataSet   Me.quoteConnection.Open()   Try     Dim quotesDS As DataSet     Dim quotesDa As SqlDataAdapter     quotesDS = New DataSet     quotesDa = New SqlDataAdapter(Me.cmdGetQuotes)     quotesDa.Fill(quotesDS)     Return quotesDS   Finally     Me.quoteConnection.Close()   End Try End Function 

Compile and test this Web method in the same way the GetQuote Web method was tested . This time the result should be a long page of XML output to the browser. This is the XML representation of the DataSet . This XML is similar to the XML output from a call to DataSet.WriteXml . This is because the XML Web service architecture serializes a DataSet by calling the DataSet.WriteXml method.

Now, it is time to create a client that consumes the DataSet from the Web service. Start by creating a new Smart Device Application the same way you created the orginal QuotableQuotesClient application, right down to the same UI. Only button-clicked handler and the UI updating code will change. Once you create the application UI, add the following member variables to the Form1 class:

 
 C# private DataSet quotesDataSet; private int curQuoteRowNdx; 

Now, double-click the Get Quotes button to bring up the button-clicked handler. Listing 9.9 contains the code for the handler.

Listing 9.9
 C# private void btnQuote_Click(object sender, System.EventArgs e) {   if(null == quotesDataSet)   {     QuoteService qs = new QuoteService();     // Set the proxy's url property to the correct url of the server     quotesDataSet =  qs.GetQuotes();     curQuoteRowNdx = 0;   }   if( quotesDataSet.Tables.Count <= 0 )   {     MessageBox.Show("Could not retreive the quotes dataset.");     return;   }   if(curQuoteRowNdx >= quotesDataSet.Tables[0].Rows.Count)     curQuoteRowNdx = 0;   DataRow quote = quotesDataSet.Tables[0].Rows[curQuoteRowNdx];   curQuoteRowNdx++;   UpdateQuoteUI(quote, 0); } VB Private Sub Button1_Click(ByVal sender As System.Object,         ByVal e As System.EventArgs) Handles Button1.Click   If quotesDataSet Is Nothing Then     Dim qs As New QuoteService     ' Set the proxy's url property to the correct url of the server     Me.quotesDataSet = qs.GetQuotes()     Me.curQuoteRowNdx = 0   End If   If quotesDataSet.Tables.Count <= 0 Then     MessageBox.Show("Could not retreive the quotes dataset.")     Return   End If   If Me.curQuoteRowNdx >= quotesDataSet.Tables(0).Rows.Count Then     Me.curQuoteRowNdx = 0   End If   Dim quote As DataRow   quote = quotesDataSet.Tables(0).Rows(curQuoteRowNdx)   curQuoteRowNdx = curQuoteRowNdx + 1   UpdateQuoteUI(quote, 0) End Sub 

The quotes DataSet is downloaded from the service only when the quotes DataSet is null . The DataSet is null the first time the Get Quotes button is clicked. On subsequent calls the quotes are cached in the local quotes DataSet , so there is no need to download them again.

If the quotes DataSet is null , then a QuoteService proxy object is created, the proxy's URL property is configured, and the GetQuotes Web method is called.

Next a check is performed to ensure that curQuoteRowNdx has stepped beyond the number of quotes in the DataSet . The curQuoteRowNdx specifies the index of the current quote in the DataSet . In this example, the application moves sequentially through the quotes every time the user clicks the Get Quotes button.

INCREASING THE PERFORMANCE OF WEB SERVICES THAT EXPOSE DATASET

When a XML Web service receives a DataSet , it calls the IXmlSerializable.ReadXml method to re-create the DataSet . This method can take a long time to execute depending on the amount of XML data. Improved performance can be seen if a custom object model is used instead of relying on the DataSet. Using the QuotesService as an example, a QuotesCollection data structure could be introduced into the XML Web service project. This collection would implement the ICollection interface and represent a collection of Quote objects. The GetQuotes method would return a QuotesCollection instead of a DataSet . The client would cycle through this collection instead of a DataTable of quote data. This will provide a significant performance increase, because the DataSet and its XML functionality would not be used at all.


Then the corresponding DataRow is retrieved from the DataSet and UpdateQuoteUI is called, which will display the quote information to the user. The UpdateQuoteUI is now implemented to use a DataRow instead of a quote data structure. There is also an integer parameter named offset of type Int32 . This offset is the column index to the first column of data. All of the other data can be found sequentially after the index. Listing 9.10 contains the new implementation of the UpdateQuoteUI method.

Listing 9.10
 C# private void UpdateQuoteUI(DataRow quote, int offset) {   lblQuote.Text = (string)quote[offset];   lblAuthor.Text = "-" + quote[offset + 1];   lblDate.Text = "Unknown" == (string)quote[offset + 2] ?     string.Empty :     (string)quote[offset + 2]; } VB Private Sub UpdateQuoteUI(ByVal quote As DataRow, ByVal offset As Int32)   Label1.Text = CType(quote(offset), String)   Label2.Text = "-" & CType(quote(offset + 1), String)   If CType(quote(offset + 2), String) = "Unknown" Then     Label3.Text = String.Empty   Else     Label3.Text = CType(quote(offset + 2), String)   End If End Sub 

Compile and run the application. The application should act exactly as it did before, except the quotes will cycle instead of being displayed in a nondeterministic order.



Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

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