Initializing the Soap Client

Initialization lets the SOAPClient read the Web Service's WSDL file so that it can create and parse the SOAP wrappers required to access the service. To initialize the SOAPClient, you specify the location of the Web Service by calling the soapClient.mssoapinit method. The method takes four arguments. The first (required) argument is the URL of the WSDL file for the Web Service you want to use. The other three arguments are optional—and you may not know any of them immediately:

■ The public Web Service identifier name—needed only if you want to access a service other than the first service identified in the WSDL file.

■ The port identifier— needed only if the <portType> element specifying the SOAP port does not appear first in the WSDL file.

■ A URL specifying the Web Service's WSML file location (not applicable to .NET-generated Web Services—you need this only if you're generating a Web Service from a COM object).

As mentioned, the first parameter to the SoapClient.mssoapinit method accepts the URL for the Web Service's WSDL file. Unfortunately, you might not have a WSDL static file (and you might not want one either, because if you change the Web Service, clients using an older copy of the WSDL file might break). Instead, you can retrieve the WSDL file from .NET Web Services in the same way that the automatic Web Service test file does—by requesting it dynamically. Use the full URL of the Web Service, but append a query string parameter of wsdl to the URL. For example:

http://localhost/CSharpASP/ch21/ch21-payment.asmx?WSDL"

Using this method, you know the WSDL file is always up to date.

The WSDL file location is relatively easy, but how do you find the name and the port identifier? The answer is to look at the WSDL file. Remember, you can use the URL with the ?wsdl query string parameter to display the WSDL file in IE. To find the name string you should use for the name parameter, look for a <binding> element in the WSDL that has a <soap:binding> element. The name attribute of the <binding> element contains the name you should use.

<binding name="ch21_paymentSoap" type="s0:ch21_paymentSoap">

<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />

<operation name="getPayment"> <soap:operation soapAction="http://CSharpASP/ch21/getPayment" style="document" /> <input>

<soap:body use="literal" /> </input> <output>

<soap:body use="literal" /> </output> </operation>

<operation name="totalPaymentAmount"> <soap:operation soapAction="http://CSharpASP/ch21/totalPaymentAmount" style="document" /> <input>

<soap:body use="literal" /> </input> <output>

<soap:body use="literal" /> </output> </operation> </binding>

The WSDL file may contain multiple <binding> elements. For example, the Mortgage Payment Calculator WSDL file contains a <binding> element for each operation type—get, post, and soap— but only the soap binding element contains a <soap:binding> element as its first child.

Note that, although the Mortgage Payment Calculator Web Service file in the CSharpASP project is named ch21-payment.asmx, the WSDL file turns the dash into an underscore (ch21_payment). In other words, it uses the .NET class name, not the filename.

You must also extract the port identifier string from the WSDL file. You'll find the correct port identifier in the appropriate <portType> element. For example, the WSDL file for the Mortgage Payment Calculator defines three portType names: <portType name="ch21 paymentHttpPost">

<portType name="ch21 paymentHttpGet"> <portType name="ch21 paymentSoap">

In this case, because you're using SOAP to communicate with the service, use the name ch21_paymentSoap for the port identifier parameter to the SoapClient.mssoapinit method:

<portType name="ch21_paymentSoap">

<operation name="getPayment">

<input message="s0:getPaymentSoapIn" /> <output message="s0:getPaymentSoapOut" /> </operation>

<operation name="totalPaymentAmount">

<input message="s0:totalPaymentAmountSoapIn" /> <output message="s0:totalPaymentAmountSoapOut" /> </operation> </portType>

You need the fourth parameter—the WSML file URL—only if you're accessing a Web Service exposed by a COM object, so it doesn't apply to this example. However, to be complete, you can generate WSDL and WSML files using a utility that the SOAP Toolkit installs called the WSDL Generator. After installing the SOAP Toolkit, you can find the WSDL Generator utility at Start ® Programs ® Microsoft SOAP Toolkit ® WSDL Generator.

The soapClient.mssoapinit method to initialize the Mortgage Payment Calculator Web Service looks like this:

Dim wsClient As MSSOAPLib.SoapClient Set wsClient = New soapClient Call wsClient.mssoapinit(

"http://localhost/CSharpASP/ch21/ch21-payment.asmx?WSDL "), _ "ch21 payment", "ch21 paymentSoap")

The code for the project is shown in Listing 22.1. Although Web Services are relatively fast once initialized, just like DCOM or any other remote invocation mechanism, they take a little while to load and execute the first time you call them. Therefore, the project uses a Sub Main routine to load a small initialization form that displays a Contacting Server... message when you first load the project. Depending on your setup, your network speed, and how long it's been since you tested or ran the Mortgage Payment Calculator Web Service from the test pages or the other sample applications, the initialization form may be visible only as a brief flash, or for several seconds.

The Main routine loads the initialization form, retrieves the Web Service initialization values from an instance of a class named InitServiceXMLReader, which reads the Web Service WSDL file URL, the service name, and the PortID from an XML file and then exposes the values as public properties. The Main routine uses those property values to call the initialization form's initService method, passing the necessary parameters. The initialization form performs the initialization, and then the Main routine hides it and displays the main form (see Listing 22.1).

Note You will need to change the URL for the initService call. To do that, open the

MortgageCalculatorClient.xml file in the project folder and modify the WSDLFileURL value so that it points to the correct server and path for the ch21-payment.asmx file on your server.

Listing 22.1: Main Subroutine for the VB6 Mortgage Payment Calculator Client Application

(modMain.bas)

Public InitServiceReader As InitServiceXMLReader

Sub main()

restart:

On Error GoTo ErrMain Load frmInit frmInit.Show DoEvents

Set InitServiceReader = New InitServiceXMLReader

InitServiceReader.InitService

With InitServiceReader

Call frmInit.InitService(.WSDLFileURL, .ServiceName,

.PortID, .WSMLFileURL)

End With frmlnit.Hide Unload frmlnit frmMain.Show vbModal ExitMain:

Exit Sub ErrMain:

' log the error (not shown) ' hide any forms still showing Unload frmlnit Unload frmMain ' display the error

If MsgBox("The application encountered a fatal error: " & Err.Description & vbCrLf & vbCrLf & "Do you want to try again?", vbCritical + vbYesNo, "Unable to Continue: Try Again?") = vbYes Then Resume restart

Else

Resume ExitMain End If End Sub

The initialization form (see Figure 22.2) creates a soap client object, calls the soapClient.mssoapinit method, raising an error if it can't initialize the Web Service properly, and then exits. The form functions as both a splash screen and a way to prevent the application from running if the Web Service can't be properly initialized. It's useful to set up and check all application initialization before users enter any values; that way, you can warn them of problems before they spend time entering data.

Vb6 Mssoaplib
Figure 22.2: The initialization form acts as a splash screen and initializes the SOAP client

The main form (frmMain) contains code to validate the input, call the Mortgage Payment Calculator Web Service, and display the results—it's very similar to the Windows Forms client you saw in the preceding chapter. As before, most of the code is in the method named Validate, which checks the user input, stripping dollar signs, percent signs, and commas from the numbers entered by the user. The interesting action happens in the highlighted section of code in Listing 22.2, which calls the Web Service and displays the results.

Listing 22.2: VB6 Code in frmMain to Call and Display the Mortgage Payment Calculator Web Service (frmMain.frm)

Const AppTitle = "MortgageCalculator"

Private Sub Form Load() Unload frmlnit pnl1.Move 0, 0, Me.Width pnl2.Move 0, pnl1.Top + pnl1.Height, Me.Width End Sub

Private Sub cmdGetPayment Click() Dim apr As Double Dim total As Double

Dim duration As Integer Dim wsClient As MSSOAPLib.soapClient Dim sPayment As String Dim dPayment As Double Dim sTotalResult As String Set wsClient = New soapClient On Error Resume Next Me.MousePointer = vbHourglass

'initialize the Web Service Call wsClient.mssoapinit(

"http://localhost/CSharpASP/ch21/ch21-payment.asmx?WSDL", "ch21 payment", "ch21 paymentSoap") If Err <> 0 Then

Me.MousePointer = vbDefault

Debug.Print "initialization failed " + Err.Description Exit Sub End If

' validate user input

If Validate(apr, total, duration) Then sPayment = wsClient.getPayment(apr, total, duration) Me.lblPaymentResult = sPayment

' strip the dollar sign from the payment string ' and get a double for the call to getTotalAmount dPayment = CDbl(Mid$(sPayment, 2)) sTotalResult = wsClient.totalPaymentAmount _

(dPayment, duration) Me.lblTotalResult = sTotalResult End If

Me.MousePointer = vbDefault End Sub

Private Function Validate(apr As Double, total As Double, duration As Integer) As Boolean Dim sAPR As String Dim sTotal As String Dim sDuration As String Dim sMsg As String Const validationError = 50000

On Error GoTo ErrValidate

' get the APR sAPR = txtAPR.Text ' ensure user entered a value If Len(Trim$(sAPR)) = 0 Then sMsg = "You must enter an APR." Err.Raise validationError, AppTitle, sMsg End If

' strip percent sign if present sMsg = "You entered an invalid value in the APR field." sAPR = Replace(sAPR, "%", "") sAPR = Trim$(sAPR) apr = CDbl(sAPR)

sMsg = "The APR must be between .01 and 100" If apr < 0.01 Or apr > 100 Then

Err.Raise validationError, AppTitle, sMsg End If

' get the total sTotal = txtTotal.Text

If Len(Trim$(sTotal)) = 0 Then sMsg = "You must enter the Amount Financed."

Err.Raise validationError, AppTitle, sMsg End If

, strip dollar sign, and commas, if present sMsg = "You entered an invalid value in the " &

"Amount Financed field." sTotal = Replace(sTotal, "$", "") sTotal = Replace(sTotal, ",", "") sTotal = Trim$(sTotal) total = CDbl(sTotal)

If total < 1000 Or total > 20000000 Then sMsg = "The Amount financed must be between " & "1000 and 20,000,000"

Err.Raise validationError, AppTitle, sMsg End If

, get the duration sDuration = txtDuration.Text

If Len(Trim$(sDuration)) = 0 Then sMsg = "You must enter the Mortgage Duration." Err.Raise validationError, AppTitle, sMsg End If sMsg = "You entered an invalid value in the " &

"Amount Financed field." duration = CInt(sDuration) If duration < 1 Or duration > 100 Then sMsg = "The Mortgage Duration must be between " &

"1 and 100." Err.Raise validationError, AppTitle, sMsg End If

Validate = True ExitValidate:

Exit Function ErrValidate:

Me.MousePointer = vbDefault Debug.Print Err.Description MsgBox sMsg, vbOKOnly, AppTitle Resume ExitValidate End Function

Was this article helpful?

0 0

Responses

  • nilde
    How initilize soapclient.mssoapinit?
    6 years ago

Post a comment