Tải bản đầy đủ (.pdf) (30 trang)

Tài liệu Programming Microsoft SQL Server 2000 with Microsoft Visual Basic .Net - P11 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (682.05 KB, 30 trang )

Form 2 reappears after the user replies to the prompt, the form
shows the first two text boxes with their prior values as well as the
fourth text box for displaying a column value. The specific value in
the bottom text box is the one matching row specified by the user’s
reply to the prompt.
Figu re 1 3 - 1 1 . The client applicat ion form for the Service1 W eb service in
the Tab leProcessor folde r.

The processing of the return values from the ColumnValues Web
method illustrates a typical scenario. A developer engineers an
application so that it can accommodate any of several scenarios. For
example, a client application makes a selection from the total set of
column values to show the column value for just one row instead of
the whole set of column values as in Figure 13-10. Figure 13-12
tracks the process from designating database and table names to
capturing the reply to the I nputBox prompt to showing the specific
column value that a user wants to view. I n the top window, the user
designates that they want results from the Custom ers table in the
Northwind database before clicking the button labeled Get Column
Value. The m iddle window shows the user indicated that the
application should show the column value for the fifth row. By the
way, the prompt adjusts automatically to show the maximum
number of rows. The application does this by running the RowCount
Web method when processing a request to show a specific row
value from the first column. The bottom window in the figure
reveals BERGS as the column value for the fifth row in the first
column. You can easily confirm this outcome for yourself by
examining the output in Figure 13-10, which shows all the column
values for the first column in the Custom ers table from the
Northwind database.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.


Figu re 1 3 - 1 2 . The client applicat ion for t he Se rvice1 W eb service in the
TablePr ocessor folder dem on stra t ing h ow it handles a request t o show a
par t icular colum n va lu e from the first colum n of the Cu stom ers t able in
the Northw ind dat aba se.

The following listing shows the code behind Form 2 that manages
the behavior of the client application for the Web service in the
TableProcessor folder. The listing starts with the instantiation of a
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
module-level variable, x ws1, for the proxy Web service. Notice how
Visual Basic .NET systematically names the second-level reference
in the proxy object. The proxy for the first Web service uses
localhost as its second name. The proxy for the deployed version
used localhost1 as its second name. This proxy variable, which is
the third one in the chapter, has localhost2 as its second name. In
all three cases, the first name for a proxy denotes the client
application’s project— namely, XMLWebServiceClients. Also, the
name for the proxy object in each case refers to the .asmx file in
the Web service, which has the name Service1 in all three
instances.
The body of the listing includes three event procedures. One is a
form Load event procedure. This event procedure merely readies
the initial look of the form. In particular, it makes the third and
fourth text boxes, along with their matching labels, invisible. The
application also includes a Click event procedure for each button on
the form. These event procedures invoke the RowCount and
Colum nValues Web methods as well as processing their return
values. As you can see, the xws1 proxy variable appears in both
Click event procedures, which is why the listing starts by
instantiating the variable at the module level.

The But ton1_Click event procedure invokes the RowCount Web
method and displays its result in TextBox3. This procedure actually
starts by m aking sure Text Box4 and its matching label are invisible.
These two controls are for displaying a column value and labeling
the return value, but a click of the Row Count button (Butt on1)
doesn’t show any column values. Next the procedure copies the
Text property values of TextBox1 and TextBox2 to memory
variables in the client application. These variables store the name of
the database and the table for the Web service to examine. After
saving the local m emory variables, the procedure uses them as
arguments while invoking the RowCount Web method. The
arguments specify for which table in which database to return a row
count. The final group of lines in the event procedure makes the
text box and label (TextBox3 and Label3) for the row count value
visible on the form. The procedure’s final line passes the converted
value type of the return value from the RowCount Web method to
the Text property of TextBox3.
The Click event procedure for Butt on2 is slightly more sophisticated
than the one for Button1. There are three reasons for this. First, the
Button2_Click event procedure invokes two Web methods instead of
one. Second, the Click event procedure for Button2 presents a
prompt to gather user feedback. Third, the event procedure stores
the return value from the Colum nValues Web method as an array
and then uses the reply to the prompt to pick a value from the
array and display it on the form.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Like the event procedure for Butt on1, the Butt on2_Click event
procedure starts by making a text box and label invisible. I n this
case, the text box and label are for the RowCount Web method’s
return value, which a click to Button2 doesn’t show. Just because

the procedure doesn’t directly show the return value from the
RowCount Web method doesn’t mean the Web method is unused in
the procedure. On the contrary, the RowCount Web method’s return
value is used early and often throughout the procedure. In fact, the
next three lines save arguments for the Web method, invoke it, and
save the return value in a memory variable, m yRowCount. Next the
procedure prom pts the user for which row in the first column to
show a column value. The procedure uses an I nput Box function for
this with the default value 1.
After obtaining a reply to the I nput Box function prompt, the
procedure concludes its data input phase from the user. All the data
it needs is in memory or available via a Web method call. Next the
procedure invokes the Colum nValues Web method and saves its
result as a string. Then the procedure strips off the leading string (
"Values in column 1 are: "
) from the return value and saves
the resulting string (st r1). This leaves str1 with just the column
values from the table named in TextBox2.
Perhaps the most interesting aspect of the procedure is the parsing
of str1 to extract individual column values that go into cells in the
m yVect or array. The array is dimensioned based on the row count
from the table named in Text Box2. This value is available via a
memory variable (m yRowCount) from the invocation of the
RowCount Web method. The procedure then opens a loop that
iterates through the column values in str1. On each pass through
the loop, the code reads the first column value in str1, which is a
substring up to but not including the first comm a. It then saves this
value in the first em pty cell in the myVector array and removes the
value, its trailing comma, and the blank space after the comma
from the str1 variable. Therefore, successive passes always have a

fresh value as the first column value in str1. The procedure
concludes by m aking TextBox4 with its matching label visible and
by selecting a cell from the m yVect or array to show based on the
user’s response to the I nputBox function prompt.
’Use cabinc_NthRoot Web Service.
Dim xws1 As New XMLWebServiceClients.localhost2.Service1(
)

Private Sub Form2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

’Hide RowCount text box and label.
TextBox3.Visible = False
Label3.Visible = False

Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
’Hide ColumnValue text box and label.
TextBox4.Visible = False
Label4.Visible = False

End Sub

Private Sub Button1_Click(ByVal sender As System.Object,
_
ByVal e As System.EventArgs) Handles Button1.Click

’Hide ColumnValue text box and label.
Label4.Visible = False
TextBox4.Visible = False


’Pass database name and table name from text boxes on
’the form to the RowCount Web method.
Dim adbname As String = TextBox1.Text
Dim atablename As String = TextBox2.Text
Dim myRowCount As Integer = _
xws1.RowCount(adbname, atablename)

’Make the RowCount label and text box visible
’before populating the text box with a value
’from the RowCount Web method.
Label3.Visible = True
TextBox3.Visible = True
TextBox3.Text = myRowCount.ToString

End Sub

Private Sub Button2_Click(ByVal sender As System.Object,
_
ByVal e As System.EventArgs) Handles Button2.Click

’Hide RowCount text box and label.
Label3.Visible = False
TextBox3.Visible = False

’Pass database name and table name from text boxes on
’the form to the RowCount Web method.
Dim adbname As String = TextBox1.Text
Dim atablename As String = TextBox2.Text
Dim myRowCount As Integer = _
xws1.RowCount(adbname, atablename)


’Print out the maximum number of rows as part of a pr
ompt
’for a selected row from a user.
Dim strInputMsg = _
"What row to max. of " & myRowCount.ToString & "?
"
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Dim intReturnedRow As Integer = _
CInt(InputBox(strInputMsg, "", "1"))

’Pass database name and table name memory values to t
he
’ColumnValues Web method and strip off leading string
’for column values.
Dim myColumnValues As String = _
xws1.ColumnValues(adbname, atablename)
Dim intToColon = InStr(myColumnValues, ":")
Dim str1 = Mid(myColumnValues, intToColon + 2, _
Len(myColumnValues))

’Dimension array and integer variable for loop.
Dim myVector(myRowCount - 1) As String
Dim intRow As Integer

’Pass string of column values to an array.
For intRow = 0 To myRowCount - 1
myVector(intRow) = _
str1.substring(0, InStr(str1, ",") - 1)
str1 = Mid(str1, InStr(str1, ",") + 2, Len(str1))

Next

’Make ColumnValue label and text box visible before
’passing array value corresponding to user selection
in
’the text box.
Label4.Visible = True
TextBox4.Visible = True
TextBox4.Text = myVector(intReturnedRow - 1)

End Sub


The SQL Se rver 2 0 0 0 W eb Ser vices Toolk it
The Web Services Toolkit simplifies the creation of Web services
based on SQL Server 2000 database objects and templates in IIS
virtual directories. Microsoft built on an earlier approach for
delivering XML functionality from SQL Server with the Web Services
Toolkit— namely, by extending the capability of the IIS virtual
directory so that it can host a Web service. The Web service from
an IIS virtual directory exposes individual database objects and
templates as Web m ethods.
After the creation of a Web service based on an IIS virtual
directory, you still use the same basic approach demonstrated in
the preceding two sections for developing a client application for
your Web service. This section starts by revealing how to design an
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
IIS virtual directory to offer a Web service. The design of the virtual
directory specifies the Web service based on a stored procedure.
The review of a core client application and a simple extension of it

equip you with the skills to build your own solutions for capturing
XML fragm ents returned from Web methods based on database
objects and templates.
Scripting a SQL Se r ver User for a Virt ual Direct ory
Although it isn’t essential to designate a SQL Server user when
specifying an II S virtual directory, it can be useful— especially when
the virtual directory hosts a Web service. Any Web service
emanating from an IIS virtual directory can have a potentially large
number of users. By using a special SQL Server user, you can set
the permissions for the special SQL Server user and be sure that
anyone who connects to the Web service will have permission to
perform the tasks enabled through the exposed Web methods. You
can also limit the ability to perform tasks through the Web service
by lim iting the permission for its special SQL Server user.
N ote
The .NET Framework contains standard security conventions,
including techniques for managing the use of encryption that
your applications m ay require for protecting a user’s identity,
managing data during transm ission, and authenticating data
from designated clients. See the “Cryptography Overview”
topic in the Visual Studio .NET documentation for more detail
on this topic. This topic is a major section within the
“Security Applications” topic, which you might also want to
review.
The following T-SQL script is meant for you to run from Query
Analyzer for the SQL Server 2000 instance that you use for the
remaining samples throughout this chapter. The script is available
among the book’s sample files as ScriptsFor13.sql. The sample is
built around the notion that this is the local SQL Server 2000
instance. If this isn’t the case, you’ll need to adjust the sample

accordingly. The script drops any prior SQL Server login for the
connected SQL Server instance and a prior user for the Northwind
database named vbdotnet1. If you incur error messages because
the user doesn’t exist, simply ignore them because the purpose of
the script is to remove a login or user only if it does exist. After
making sure vbdotnet1 is free for assignment, the script adds a new
user named vbdotnet1 and grants access to the Northwind
database. Recall that the Northwind database is one of the SQL
Server sample databases. The database’s public role grants any
user access to m ost database objects that ship as part of the
database. For exam ple, vbdotnet1 has automatic permission to run
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
all stored procedures, such as the Ten Most Expensive Products
stored procedure, which is one of the built-in user-defined stored
procedures for the database.
Notice that this script uses “/ * ” to mark the beginning of the code
com m ent that stretches over multiple lines, and “* / ” to end it.
/*Run from member of sysadmin fixed server role.
Ignore errors if user does not already exist.
*/

USE Northwind

EXEC sp_revokedbaccess ’vbdotnet1’
EXEC sp_droplogin @loginame = ’vbdotnet1’
GO

Add vbdotnet1 user with known permissions.

EXEC sp_addlogin

@loginame = ’vbdotnet1’,
@passwd = ’passvbdotnet1’,
@defdb = ’Northwind’
EXEC sp_grantdbaccess ’vbdotnet1’
GO

Building a W eb Service in an I I S Virt ua l D irectory
Now that we have a SQL Server user, we can proceed through the
steps for creating an IIS virtual directory. This directory will contain
the contract for a Web service. You can create a new IIS virtual
directory by choosing Programs from the Windows Start menu, then
SQLXML 3.0, and then Configure IIS Support. This opens the IIS
Virtual Directory Management utility for SQLXML 3.0. In order to
open the utility, you must, of course, have already installed Web
Release 3 (SQLXML 3.0). See the “Web Services from the Web
Services Toolkit” section for a URL to download Web Release 3
along with the Web Services Toolkit.
With the IIS Virtual Directory Management utility open, expand the
folder for the local Web server. Then right-click Default Web Site
within the local Web server, choose New, and then choose Virtual
Directory. This opens a multi-tabbed dialog box that lets you set the
properties of a new virtual directory. You can use the New Virtual
Directory Properties dialog box to create the virtual directory by
following these instructions:
1. On the General tab, name the directory Chapter13, and give
the virtual directory the path c: \ inetpub\ wwwroot\ Chapter13.
You can type the path or use the Browse button to navigate to
the folder. Although the utility allows you to create a new
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
folder from within the utility, som e may find it easier to create

the folder before opening the utility.
2. On the Security tab, select the SQL Server radio button. Then
enter vbdotnet1 in the User Name text box and
passvbdotnet1 in the Password text box. Confirm the
password before moving off the tab.
3. On the Data Source tab, accept the default settings of the
local SQL Server and default database for the current login.
4. On the Settings tab, leave Allow Template Queries selected
and also select Allow POST.
5. On the Virtual Names tab, you set up the virtual directory
through which you can deliver Web services. With < New
virtual name> highlighted in the Defined Virtual Names list
box, enter SoapFor13 in the Name text box. Then select soap
from the Type list. Next, in the Path text box, enter the path
for your virtual directory, namely
c: \ inetput\ wwwroot\ Chapter13. Finally click Save to enable
the configuration of your Web service associated with the
SoapFor13 virtual name.
Once you’ve clicked Save, the Configure button is enabled.
6. While still in the Virtual Names tab, click Configure (see Figure
13-13) to select SQL Server stored procedures and user-
defined functions to expose as Web methods. You can also
expose templates through the Web service. Although your
database objects and templates m ust exist before you can
expose them, the Web Services Toolkit doesn’t expose them
until you explicitly configure it to make the Web service offer
Web methods based on a stored procedure, user-defined
function, or template.
Figu re 1 3 - 1 3 . The V irt ual Nam e t ab for t he New Virtual Dire ctory
Proper t ie s dialog box for the SoapFor 1 3 W eb service in the

Chapt er1 3 virt ual dir ect ory.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

7. After you click Configure, the Soap Virtual Name Configuration
dialog box opens so that you can specify items to expose as
Web methods. If you are going to expose a stored procedure
or a user-defined function, designate SP as the Type;
otherwise, select Template to designate a template as the
source for a Web method. You can designate an item by using
the Browse button (…) to browse sources for a Web m ethod in
the Web service hosted by the virtual directory. By clicking
the Browse button with SP selected as the Type, I was able to
pick Ten Most Expensive Products as the source for a Web
method. I accepted the default selection to return the result
set from the stored procedure as XML objects. With this
selection, you can retrieve m ultiple results (or just one) from
a stored procedure. Figure 13-14 shows the dialog box just
before I click Save to expose the stored procedure as a Web
method.
8. Click OK to save the configuration of the Web Service and
close the Soap Virtual Name Configuration dialog box.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Figu re 1 3 - 1 4 . The Soap Virtua l N a m e Con figu rat ion dia log box
displaying the settings for t he Ten_ M ost_ Ex pen sive_ Product s W eb
m ethod just before saving them .

You can improve your debugging process by disabling various
caching options.
9. Click the Advanced tab in the New Virtual Directory Properties
dialog box. Consider selecting all three options for disabling

different types of caching. These selections improve the
operation of your Web service, but the caching can be
distracting in some debugging and code updating operations.
10. Click OK to save the settings you’ve chosen and close
the New Virtual Directory Properties dialog box.
Now you’re ready to test the Web service. After you finish
debugging and refining your Web service, restore the caching
features because they speed up the operation of a Web
service in normal operation.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
N ote
The book’s sample files include the Chapter13 virtual
directory folder for reference’s sake. In order to create the
virtual directory so that you can manage it and use it, you’ll
need to follow the instructions for its creation in this section.
When a subsequent section edits the SoapFor13 Web service
hosted by the Chapter13 virtual directory, you’ll need to
follow the steps for that as well.
Building a Client Applica t ion t o Show an XML Fragm ent
Web services created with the SQL Server 2000 Web Services
Toolkit don’t have a built-in test interface. In addition, you connect
them to a client application slightly differently than Web services,
which you build directly with Visual Studio .NET. Nevertheless, the
broad outline of the testing process with a client application is
similar. In both cases, a .wsdl file formally defines the Web service
and specifies any input and outputs associated with individual Web
methods. I n addition, you must create a Web reference in the client
application that points at the Web service.
Create a new form named Form3 in the XMLWebServiceClients
project. Add two label controls. Size the form and controls about as

they appear in Figure 13-15 later in this section. (The form is also
available in the XMLWebServiceClients project among the book’s
sample files.) The arrangement and sizing of the form and its
controls are intended to accommodate the display of the entire XML
fragment returned by the Ten_Most_Expensive_Product s Web
method. Make Form 3 the startup object for the
XMLWebServiceClients project so that the form opens when you
start the project.
In the module behind Form 3, add a Web reference to the
SoapFor13 Web service by choosing Add Web Reference from the
Project menu. In the address box of the Add Web Reference dialog
box, type the following URL with its trailing param eter:
ht tp: / / localhost/ Chapt er13/ SoapFor13?wsdl
Then press Enter. This populates the left pane of the Add Web
Reference dialog box with a representation of the .wsdl file for the
SoapFor13 Web service. The right pane includes a single link with
the text View Contract. Click the Add Reference button to create a
Web reference for use with a proxy variable. If you have been
creating the samples throughout the chapter, the name for this Web
reference in the Web References folder of Solution Explorer is
localhost 3. No matter what its name, the reference should include
an item named SoapFor13.wsdl. This .wsdl file contains the formal
description for the Web service. Any proxy variable based on this
Web reference will enable you to run the
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Ten_Most_Expensive_Product s Web method and display the result
set returned as an XML fragment. The result set from the stored
procedure is available as an XML document fragment because the
example selected this output format in Figure 13-14.
The next listing shows the code behind the form in Figure 13-15. As

you can see, it consists of a single form Load event procedure.
When the form opens, the procedure connects to the SoapFor13
Web service and invokes the Ten_Most _Expensive_Product s Web
method. It collects the XML fragment returned by the method in an
array of Response objects. The Response object is the most basic
kind of object in Visual Studio .NET; this type of object can
accommodate any other kind of object or type. Since the Web
service can present either an XML document or a SqlMessage
object, the application needs Response objects to accommodate
either outcome. The SqlMessage object can return SQL Server error
messages and warnings to an application.
Using an array of objects accommodates the possibility of multiple
result sets from a single stored procedure or template file. Although
this sample has a single result set, the sample’s design illustrates
the For loop syntax for iterating through the members of a
Response object array. A Select…Case statement sends the
Response object to the appropriate code for processing. Because
this is a very simple application, the code just processes an object
containing an XML fragment. The processing consists of a pair of
statements that copy the XML fragment in the Response object to
the Text property of the second label on Form 3. Whenever you
choose to output the result set or sets from a Web method as XML
objects, you’ll have to process the output in this style— that is, with
a Select…Case statement nested within a For loop that iterates
through the objects returned from the Web method.
Private Sub Form3_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

’Declare Web service xws1 as type named soap in
’localhost4 Web reference.

Dim xws1 As New XMLWebServiceClients.localhost3.SoapF
or13()

’Declare object for return from Web service method.
Dim response As New Object()
Dim result As System.Xml.XmlElement

’Declare integer for iterating through multiple
’result sets that the Web service method can return.
Dim int1 As Integer

’Save return from Web service method as an object.
response = xws1.Ten_Most_Expensive_Products

Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
’Iterate through result sets.
For int1 = 0 To UBound(response)

Select Case response(int1).GetType().ToString()
Case "System.Xml.XmlElement"
’Pass int1 result set to result and displ
ay
’in list box and Output window.
result = response(int1)
Label2.Text = result.OuterXml
Case Else
’Handles end of result sets and other
’special returns.
End Select


Next

End Sub

Figure 13-15 shows Form 3 open from the XMLWebServiceClient
project. The form contains two labels. The top label has a fixed Text
property assignment. It always shows “XML fragment: ”. The
contents of the bottom text box can change if the ten most
expensive products change because of a price revision, the addition
of new products, or the dropping of existing products. The product
name and unit price values are delimited by opening and closing
tags. Although this format may be convenient for com puters to
process and is readable by humans, it is verbose. That’s because
every value has a pair of tags, and there are additional tags to mark
the beginning and ending of each row (< row> and < / row> ) as well
as the beginning and ending of the XML fragment (< SQLXML> and
< / SQLXML > ).
Figu re 1 3 - 1 5 . Form 3 from t h e XMLW ebServiceClient s proje ct show ing the
ou t put from t he Ten _ M ost_ Expen sive _ Product s W e b m e t h od in t h e
SoapFor1 3 W eb service.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

Populating a ListBox Control w it h an XM L Service
Figure 13-15 is interesting, but it’s unlikely that you’ll want to show
many clients of your Web services an XML fragment. It’s m ore likely
that they will want to view the tag values in a control than a
verbose XML fragment including tags. In the case of the display in
Figure 13-15, they might prefer to see a ListBox control with 10
items, showing product name and price in descending order. The
sample in this section extends the preceding one to achieve this

goal.
You can implement this sample by creating a new form, For m 4, in
the XMLWebServiceClients project. Add a list box control and the
code listing in this section. Make Form4 the startup object for the
project. I f you have the Web reference defined as in the preceding
sample, pressing F5 will cause the form to open and show the ten
most expensive products in a list box. (See Figure 13-16.) By
adding custom code, such as we will show later in this chapter, you
can enable interactivity with data returned by a Web service from
within a Windows form control.
Once you understand that your applications can capture the result
set from a stored procedure as a Response object containing an
XML fragm ent, it’s easy to craft a solution like the one in Figure 13-
16. All your application has to do is parse the XML fragment to
extract the tag values, combine the product name and price in a
form suitable for the ListBox control, and then add the combined
item to the control.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Figu re 1 3 - 1 6 . A List Box cont r ol on Form 4 show in g the p roce sse d outpu t
from t he Ten_Most_ Exp ensive_Products W eb m e t hod in t h e SoapFor 1 3
W e b se rvice.

The following listing illustrates how you can achieve this. The
solution relies on two procedures. The first is an extension of the
form Load event procedure from the preceding sample. The second
procedure is new to this chapter (but you may recall it from Chapter
12). The new code for this procedure as well as the new procedure
in this chapter appear in bold type. The primary feature of the
extension is the insertion of a Do…While loop within the For loop
that extracts the XML fragment as a response object.

The Do…While loop uses two string variables, str1 and st r2, to
manipulate the XML returned from the response object returned by
the Ten_Most_Expensive_Product s Web method. For example, str1
stores the current working version of the return value from the Web
method. In successive passes through the Do…While loop, the
procedure extracts the first values for product name and price from
the XML fragment. The form Load event procedure uses the
MyTagValue function procedure to extract the product name and
price values. The form Load event procedure then combines the two
values as a new comma-delimited string in str2, which the
procedure adds as an item to ListBox1. Before iterating through the
loop again, the code uses the Right function to remove from st r1
the XML associated with the added item. When there are no
remaining tags in str1 with price inform ation, the Do…While loop
releases control to the outer For loop, which leads, in turn, to the
opening of Form 4 with the populated list box.
As indicated earlier, the MyTagValue function procedure initially
appeared in Chapter 12. This procedure uses fam iliar string
manipulation techniques to extract tag values from an XML
fragment. The calling procedure simply passes the tag name and
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
the XML fragment. The function returns the first tag value in the
string with starting and ending tags within the fragm ent m atching
the tag name passed to it. The reuse of such a sim ple procedure
from Chapter 12 without any modification illustrates the power of
thinking of XML fragments as strings.
Private Sub Form3_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

’Declare Web service xws1 as type named soap in

’localhost4 Web reference.
Dim xws1 As New XMLWebServiceClients.localhost3.SoapFor13
()

’Declare object for return from Web service method.
Dim response As New Object()
Dim result As System.Xml.XmlElement

’Declare integer for iterating through multiple
’result sets that the Web service method can return.
Dim int1 As Integer

’Save return from Web service method as an object.
response = xws1.Ten_Most_Expensive_Products

’Declare variables for processing XML fragment.
Dim str1 As String
Dim str2 As String

’Iterate through result sets.
For int1 = 0 To UBound(response)

Select Case response(int1).GetType().ToString()
Case "System.Xml.XmlElement"
’Pass int1 result set to result and display
’in list box and Output window.
result = response(int1)
str1 = result.OuterXml

’Iterate through column values in XML string

’within Web service method output.
Do While InStr(str1, "</UnitPrice>") > 0
str2 = MyTagValue("TenMostExpensiveProduc
ts", str1)
str2 = str2 & ", " & MyTagValue("UnitPric
e", str1)
ListBox1.Items.Add(str2)
str1 = Microsoft.VisualBasic.Right(str1,
_
Len(str1) -
(InStr(str1, "</UnitPrice>")) - _
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Len("</UnitPrice></row>") + 1)
Loop
Case Else
’Handles end of result sets and other
’special returns.
End Select

Next

End Sub

Function MyTagValue(ByVal TagName As String, _
ByVal strXML As String)

’Declare and compute constants for this tag.
Dim str1 = "<" & TagName & ">"
Dim str2 = "</" & TagName & ">"
Dim int1, int2 As Integer

int1 = InStr(strXML, str1) + Len(str1)
int2 = InStr(strXML, str2)

’Compute tag value and return it.
’strXML is string with XML to parse.
’int1 is start position.
’int2 - int1 calculates number of characters.
Dim TagValue As String = Mid(strXML, _
int1, int2 - int1)
Return TagValue

End Function


More on Popula t ing Cont rols w it h W eb Services
This section drills deeper into building Web services with the SQL
Server 2000 Web Services Toolkit and client applications with Visual
Studio .NET. I n particular, the emphasis is on populating controls on
Windows Forms. Client applications created with Windows Forms
can interoperate freely with Web services over the Web just as if
the client were available locally. In addition to showing how to
populate controls, this section also illustrates how to provide
interactivity with Web services through Windows Form s. These
client features work equally well whether you create your Web
service application with the Web Services Toolkit or Visual Studio
.NET.
Adding Cust om D at abase Obj ects as W eb M ethods
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
The samples in the preceding section created Web services for an
existing stored procedure in the Northwind database. Sometimes

our applications benefit from, or even require, the creation of
custom database objects. When this is the case for a Web services
solution, you need to add the custom database objects to the
database. Then, in a separate step, you must expose your new
objects through the Web service. Typically, this will require editing a
previously existing Web service. The steps described in this section
illustrate how to perform these actions.
T- SQL for Cre a t in g Sa m ple Dat ab ase Ob jects
The next two code samples for client applications will work with
result sets returned by two custom database objects for the
Northwind database. One of these objects is a stored procedure,
and the other is a user-defined function. The stored procedure
returns all the CategoryI D and CategoryName column values from
the Categories table. The user-defined function returns
ProductNam e column values from the Products table. A WHERE
clause in the user-defined function causes the function to return
just product names that are from a specified category as designated
by a CategoryI D parameter. Therefore, one of the benefits of this
database object is that it illustrates the syntax and procedures for
using parameters with Web services.
The following T-SQL listing is to be run from Query Analyzer. The
listing is available among the book’s sample files as
ScriptsFor13.sql. If you want, you can adapt the samples for
running directly from Visual Studio .NET. (See Chapter 11 for
samples demonstrating this approach.) However, it is m uch easier
to run the scripts from Query Analyzer if you’re fam iliar with it. (See
the last section in Chapter 1 if you don’t already have this
background.) Use a login for Query Analyzer that belongs to the
sysadmin group.
The scripts for creating the stored procedure and the user-defined

function follow parallel paths. First they drop any prior version of
the database object. Next they create a new version of the object.
Finally they explicitly grant the vbdotnet1 user permission to use
the object. Recall that vbdotnet1 is the user for the Chapter13
virtual directory. Without granting the user permission for the
object, you won’t be able to expose the objects as Web methods for
the SoapFor13 Web service originating from the Chapter13 virtual
directory.
/*
Run from member of sysadmin fixed server role.
Ignore errors if user does not already exist.
*/

USE Northwind
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

Drop udpListOfCategoryNames if it exists.
IF EXISTS (SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = ’udpListOfCategoryNames’)
DROP PROCEDURE udpListOfCategoryNames
GO

Then, create udpListOfCategoryNames, and give
vbdotnet1 permission to execute it.
CREATE PROCEDURE udpListOfCategoryNames
AS
SELECT CategoryID, CategoryName
FROM Categories
GO


GRANT EXEC ON udpListOfCategoryNames TO vbdotnet1
GO

Drop udfProductsInACategory if it exists.
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = ’udfProductsInACategory’)
DROP FUNCTION udfProductsInACategory
GO

Then, create it, give vbdotnet1
permission to select from it.
CREATE FUNCTION udfProductsInACategory(@MyCategoryID int)

RETURNS TABLE
AS
RETURN(
SELECT ProductName
FROM Products
WHERE CategoryID = @MyCategoryID
)
GO

GRANT SELECT ON udfProductsInACategory TO vbdotnet1
GO

Updat in g a W eb Service w it h t he W e b Se rvices Toolkit
After adding custom database objects to a database, you can
expose the objects as Web methods through a virtual directory

pointing to the database. The virtual directory must have a soap
virtual name, such as SoapFor13, which is the virtual soap name for
the Chapter13 virtual directory. If you have an existing soap name,
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
you can edit it according to the instructions in this section. If you
don’t already have a soap name for a virtual directory, you can use
the instructions in the “Building a Web Service in an IIS Virtual
Directory” section to create a new soap virtual name.
Begin by exposing the two new database objects as Web methods
by double-clicking the Chapter13 virtual directory in the II S Virtual
Directory Management utility. On the Virtual Names tab of the
Chapter13 Properties dialog box, highlight SoapFor13 and click
Configure. This opens the Soap Virtual Name Configuration dialog
box. Click the Browse button (…) to select
udpListOfCategoryNam es. Select Single Dataset for the output
format. Name the Web m ethod udpListOfCategoryNam esAsDataset.
Figure 13-17 shows the Soap Virtual Name Configuration dialog box
just before saving the settings for the udpListOfCategory-
Nam esAsDataset Web method. Click Save to save the specification
for the Web method. You can follow the sam e general approach to
exposing the udfPr oductsI nACategory user-defined function as a
Web method. Assign udfProductsI nACategoryAsDataset as its Web
method name.
Figu re 1 3 - 1 7 . The Soap Virtua l N a m e Con figu rat ion se t t ings for t he
udp List OfCat e goryN am esAsDataset W e b m ethod.

Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Populating a Da t aGrid a n d a ListBox w it h a W eb Met hod
Using the revised Web service gives you a chance to explore more
ways of how to tap Web services from within Visual Basic .NET

applications. Before you can take advantage of the revisions, you
need to refresh the Web reference connecting the
XMLWebServiceClients project to the Web service. Curiously, you do
this by following the same steps as for adding a new Web reference.
Start the refresh process by choosing Add Web Reference from the
Project menu within the XMLWebServiceClients project. In the Add
Web Reference dialog box that opens, enter
ht tp: / / localhost/ Chapt er13/ SoapFor13?wsdl in the Address box.
Then press Enter and click Add Reference. This opens the dialog box
shown in Figure 13-18. Click Yes to update the Web reference.
Without these steps, your client application won’t be able to use the
Web methods for the udpList OfCategoryNames and
udfProductsI nACategory database objects added previously.
Figu re 1 3 - 1 8 . Dialog box for updat in g a W e b refer ence, d ispla yed w hen
you sta rt t o add a n ew W eb r efe ren ce to a n update d W eb service. Click
Yes to update the e xist in g W eb refe rence w ith ou t adding a n ew one.

Now that the XMLWebServiceClients project has an updated Web
reference, we can put the new Web methods to use. The
udpListOfCategoryNam es stored procedure is similar to the Ten
Most Expensive Products stored procedure in that neither procedure
accepts a parameter. However, the Web methods for the database
objects are distinct in ways that affect the syntax for using them.
Recall that the Ten_Most_Expensiv e_Products Web method formats
its output as XML objects. On the other hand, the
udpListOfCategoryNam esAsDataset Web method formats its result
as a single data set. By specifying its output as a single data set,
you know precisely what the format of the return from the Web
method will be. (There’s no chance of a SqlMessage object in the
output stream associated with the Web method.) Therefore, the

syntax for reading the output can be m ore straightforward. When
you have only one result set from a database object, the Single
Dataset format is a great output format for simplifying the
processing of your client application.
You can get a hands-on feel for using the
udpListOfCategoryNam esAsDataset Web method by adding a new
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
form with DataGrid and ListBox controls. Form 5 in Figure 13-19
shows the basic design for the sample. The Design view shows two
controls on a Windows form. The left control is an empty DataGrid
control; its Properties window shows the control’s name as
DataGrid1. The other control on the form shows its name as
List Box1. By m aking Form5 the startup object for the
XMLWebServiceClients project, you can invoke the form’s Load
event procedure by starting the project. In this event procedure,
you can load data from the SoapFor13 Web service into both
controls.
The following listing shows the form Load event procedure for
Form 5. It starts by instantiating a proxy variable, xws1, for the
SoapFor13 Web service, which is denoted by the Web reference
named localhost 3 in the client application. Because I updated the
Web reference as described previously, this sample in the
XMLWebServiceClients project can invoke the
udpListOfCategoryNam esAsDataset Web method. This Web
method’s definition returns a single data set. When returning a
result set from a stored procedure as a single data set, you must
designate an integer returnvalue argument as you invoke the Web
method. This returnvalue argument makes available the return code
for a stored procedure; syntax conventions require the returnvalue
argument even when the stored procedure has no return code.

Chapter 4 refers to return codes from stored procedures as return
status values as it illustrates their use.
Figu re 1 3 - 1 9 . Form 5 cont ains a p air of con t rols t hat the code behin d the
form w ill populate by in voking t h e udpListOfCa tegoryN am esAsD ataset
W eb m ethod.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

N ote
When a stored procedure has no return code or return status
value, the returnvalue argument for a Web method assumes
the value 0.
After copying the result set from the stored procedure to a data set
in the client application, the code assigns the data set to the
DataSource property of DataGrid1. In addition, the procedure
passes -1 as an argument to the Expand method for the DataGrid
control. This opens the row indicator on DataGrid1 so that a user
can click it to view the data in the control. Without this setting, a
user would need to click the Expand control on Dat aGrid1 to show
the row indicator. (See Figure 13-20 for a view of the row indicator
and its parent Expand/ Contract control.)
The last two blocks of code handle iterating through the returned
data set from the Web m ethod and populating the items within
List Box1 based on the colum n values for CategoryI D and
CategoryName. Because CategoryI D has a SQL Server int data
type, you gain performance by explicitly specifying it as a string for
concatenation with a string constant (", ") and the CategoryNam e
column value, which is a string value.
Private Sub Form5_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load


Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
’Declare Web service xws1 as SoapFor13 in the
’localhost3 Web reference.
Dim xws1 As New XMLWebServiceClients.localhost3.SoapF
or13()

’Save return from Web service method as a data set;
’syntax mandates specification of a returnvalue param
eter.
Dim das1 As System.Data.DataSet
Dim returnvalue As Integer
das1 = _
xws1.udpListOfCategoryNamesAsDataset(returnvalue)

’Set data grid to display returned data set.
DataGrid1.DataSource = das1
DataGrid1.Expand(-1)

’Declare a row and a string.
Dim MyRow As DataRow
Dim str1 As String

’Iterate through data set rows and insert
’in the list box column values one row at a time.
For Each MyRow In das1.Tables(0).Rows
str1 = MyRow(0) & ", " & MyRow(1)
ListBox1.Items.Add(str1)
Next

End Sub


Figure 13-20 shows the result of opening the XMLWebServiceClients
project with Form 5 as the startup object. The top window shows the
form after opening but before the row indicator in the DataGrid
control is expanded to reveal the data source behind the data grid.
Notice that this row indicator is a child control of an
Expand/ Contract control within the DataGrid control. Even before
the row indicator in the DataGrid control is clicked, the list box
shows its values. However, the list box doesn’t provide the same
degree of data formatting flexibility available with a data grid. The
bottom window shows the data grid after a click of the row indicator
and after the default width of its second column has been expanded
slightly. One of the advantages of the data grid is a user’s ability to
manipulate the control.
Figu re 1 3 - 2 0 . The D a t aGrid control on Form 5 let s t he user inte ract w it h it
to cont rol w h en th e dat a is displaye d an d to control the w idth of t h e
colum ns.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

×