Chapter 14: Web Services and Exchange


XML Web services allow you to expose programmable services to other applications or programmers. You can build XML Web services in two ways. The first way is by using Microsoft Visual Studio 6.0 and the SOAP Toolkit. The second way is to use Visual Studio .NET, which has built-in support for building and consuming Web services. This section will look at both techniques ”you can decide which way is best for your needs.

Building a Web Service Using Visual Studio 6.0 and the SOAP Toolkit

To build a Web service using Visual Studio 6.0 and the SOAP Toolkit, you must first download and install the SOAP Toolkit from http://msdn.microsoft.com/soap . Using the toolkit, building a Web service is easy ”you simply create the DLL that will implement your functionality. The Toolkit takes your DLL and creates a Web Services Definition Language (WSDL) file that contains the description of the methods , their parameters, and their return values for the DLL that implements your Web service. For our example, we will implement a free/busy lookup Web service. The following code for our free/busy lookup DLL was written using Visual Basic. Notice that the DLL exposes a public function as the main entry point that other applications can call:

 Public Function GetFreeBusy(strDirURL As String, _                             strUserNames As String, _                             strStartDate As String, _                             strEndDate As String, _                             strInterval As String) As String     On Error Resume Next     'This function looks up free/busy information for users.     'User names must be email addresses separated by commas.     'The return value is a string of freebusy values for     'the users, separated by commas.          'Make sure a directory URL was passed     If strDirURL = "" Then         GetFreeBusy = "You must pass a directory URL " & _                       "in the format LDAP://directory"         Exit Function     End If          If Not (IsDate(strStartDate)) Then         'Not a date         GetFreeBusy = "Start Date is not a valid date!"         Exit Function     End If          If Not (IsDate(strEndDate)) Then         'Not a date         GetFreeBusy = "End Date is not a valid date!"         Exit Function     End If          If Not (IsNumeric(strInterval)) Then         GetFreeBusy = "You must enter a number for the interval."         Exit Function     ElseIf CInt(strInterval) <= 0 Then         GetFreeBusy = "You must enter a positive number for the interval."         Exit Function     End If          'Make sure that user names were passed     arrUserNames = Split(strUserNames, ",")     If UBound(arrUserNames) < 0 Then         'No usernames passed.  Error and exit.         GetFreeBusy = "There were no user names passed."         Exit Function     End If          'Start building the string array for the free/busy info     strFreeBusy = ""     For x = LBound(arrUserNames) To UBound(arrUserNames)         If strFreeBusy = "" Then             strFreeBusy = strFreeBusy & PrivGetFreeBusy(arrUserNames(x), _                           strDirURL, strStartDate, strEndDate, strInterval)         Else             strFreeBusy = strFreeBusy & "," & _                           PrivGetFreeBusy(arrUserNames(x), strDirURL, _                           strStartDate, strEndDate, strInterval)         End If     Next          GetFreeBusy = strFreeBusy End Function      Private Function PrivGetFreeBusy(strUserName as String, _                                     strDirURL as String, _                                     strStartDate as String, _                                     strEndDate as String, _                                     strInterval as String) As String     On Error Resume Next     Dim oAddressee As CDO.Addressee     Set oAddressee = CreateObject("CDO.Addressee")     oAddressee.EmailAddress = strUserName     bFound = oAddressee.CheckName(strDirURL)     If bFound = False Then         PrivGetFreeBusy = "Could not resolve username: " & strUserName         Exit Function     End If          'Get the freebusy information     PrivGetFreeBusy = oAddressee.GetFreeBusy(strStartDate, strEndDate, _                                              strInterval)     Set oAddressee = Nothing End Function 

Next you generate a Web Service Description Language (WSDL) file and a Web Services Meta Language (WSML) file for your DLL. The WSDL file is an XML file that is a contract between the client and the server. It describes the format that the client should send to the server to call the Web service. The WSDL file for the free/busy Web service is shown here:

 <?xml version='1.0' encoding='UTF-8' ?> <!-- Generated 12/10/01 by Microsoft SOAP Toolkit WSDL File Generator, Version 1.02.813.0 --> <definitions  name ='VS6FB'   targetNamespace = 'http://tempuri.org/wsdl/'    xmlns:wsdlns='http://tempuri.org/wsdl/'    xmlns:typens='http://tempuri.org/type'    xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'    xmlns:xsd='http://www.w3.org/2001/XMLSchema'    xmlns:stk='http://schemas.microsoft.com/soap-toolkit/wsdl-extension'    xmlns='http://schemas.xmlsoap.org/wsdl/'>    <types>       <schema targetNamespace='http://tempuri.org/type'          xmlns='http://www.w3.org/2001/XMLSchema'          xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'          xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'          elementFormDefault='qualified'>       </schema>    </types>    <message name='FreeBusy.GetFreeBusy'>       <part name='strDirURL' type='xsd:string'/>       <part name='strUserNames' type='xsd:string'/>       <part name='strStartDate' type='xsd:string'/>       <part name='strEndDate' type='xsd:string'/>       <part name='strInterval' type='xsd:string'/>    </message>    <message name='FreeBusy.GetFreeBusyResponse'>       <part name='Result' type='xsd:string'/>       <part name='strDirURL' type='xsd:string'/>       <part name='strUserNames' type='xsd:string'/>       <part name='strStartDate' type='xsd:string'/>       <part name='strEndDate' type='xsd:string'/>       <part name='strInterval' type='xsd:string'/>    </message>    <portType name='FreeBusySoapPort'>       <operation name='GetFreeBusy' parameterOrder=       'strDirURL strUserNames strStartDate strEndDate strInterval'>          <input message='wsdlns:FreeBusy.GetFreeBusy' />          <output message='wsdlns:FreeBusy.GetFreeBusyResponse' />       </operation>    </portType>    <binding name='FreeBusySoapBinding' type='wsdlns:FreeBusySoapPort' >       <stk:binding preferredEncoding='UTF-8'/>       <soap:binding style='rpc'       transport='http://schemas.xmlsoap.org/soap/http' />       <operation name='GetFreeBusy' >          <soap:operation          soapAction='http://tempuri.org/action/FreeBusy.GetFreeBusy' />          <input>             <soap:body use='encoded'             namespace='http://tempuri.org/message/'             encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />          </input>          <output>             <soap:body use='encoded'             namespace='http://tempuri.org/message/'             encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />          </output>       </operation>    </binding>    <service name='VS6FB' >       <port name='FreeBusySoapPort' binding='wsdlns:FreeBusySoapBinding' >          <soap:address location='http://thomriznt52/vs6fb/VS6FB.WSDL' />       </port>    </service> </definitions> 

SOAP also requires a server-based WSML file, which provides the information that maps the operations of the service (as described in the WSDL file) to specific methods of the COM object. The WSML file determines which COM object and method should be used to service any requests . The WSML file for the sample is shown here:

 <?xml version='1.0' encoding='UTF-8' ?> <!-- Generated 12/10/01 by Microsoft SOAP Toolkit WSDL File Generator, Version 1.02.813.0 --> <servicemapping name='VS6FB'>    <service name='VS6FB'>       <using PROGID='ExchWS.FreeBusy' cachable='0' ID='FreeBusyObject' />       <port name='FreeBusySoapPort'>          <operation name='GetFreeBusy'>             <execute uses='FreeBusyObject' method='GetFreeBusy'             dispID='1610809344'>                <parameter callIndex='1' name='strDirURL'                elementName='strDirURL' />                <parameter callIndex='2' name='strUserNames'                elementName='strUserNames' />                <parameter callIndex='3' name='strStartDate'                elementName='strStartDate' />                <parameter callIndex='4' name='strEndDate'                elementName='strEndDate' />                <parameter callIndex='5' name='strInterval'                elementName='strInterval' />                <parameter callIndex='-1' name='retval'                elementName='Result' />             </execute>          </operation>       </port>    </service> </servicemapping> 

You might wonder how to go about generating these files. Well, you could attempt to generate the files by hand, but a much simpler and less error-prone approach is to use the WSDL generator tool from the SOAP Toolkit (shown in Figure 14-1).

click to expand
Figure 14-1: The WSDL generator tool from the SOAP Toolkit

This tool outputs the files you need to create and call your Web service. The only other thing you need to do is test the service. The sample includes a consumer of the Web service. It is just a simple Visual Basic application that allows you to specify users, dates, the directory server, and the free/busy interval to use. The sample is shown in Figure 14-2.

click to expand
Figure 14-2: The free/busy Web service consumer application

The consumer application uses the Microsoft SOAP Type Library and its SOAPClient object to talk to the Web service. The SOAPClient object makes it easy to connect to and call methods on a Web service. As you can see in the following code from the consumer application, the SOAPClient object has an MSSOAPINIT method that takes a WSDL file and a WSML file as arguments. If the method can successfully open these files from the Web service, the SOAPClient object will be initialized and can be used against the Web service. The SOAPClient object can then call Web service methods directly, and you can retrieve any failures or errors through the SOAPClient object as well.

 Option Explicit      Private mSoapClient As SoapClient Dim strServerResponse As String      Private Sub cmdConnect_Click()     On Error GoTo ErrorHandler          'See if there are any users     Dim NewSoapClient As New SoapClient     Dim WSDL As String     Dim WSML As String          If frmConnect.Connect(Me, WSDL, WSML) Then         Me.MousePointer = vbHourglass         NewSoapClient.mssoapinit WSDL, , , WSML         Set mSoapClient = NewSoapClient         cmdRefresh.Enabled = True         Me.MousePointer = vbNormal     End If          Exit Sub      ErrorHandler:          Me.MousePointer = vbDefault          If NewSoapClient.faultstring <> "" Then         MsgBox "Connect failed. " & NewSoapClient.faultstring, _                vbExclamation     Else         MsgBox "Connect failed. " & Err.Description, vbExclamation     End If          Err.Clear End Sub      Private Sub cmdRefresh_Click()     On Error GoTo ErrorHandler          listResponse.Clear     'Make sure the end date is not before the start date     If DateDiff("d", monthStart.Value, monthEnd.Value) < 0 Then         MsgBox "The end date must be after the start date!", _                vbOKOnly + vbExclamation         Exit Sub     End If          'Make sure interval is a #     If Not (IsNumeric(txtInterval.Text)) Then         MsgBox "You must enter a number for the interval.", _                vbOKOnly + vbExclamation         Exit Sub     ElseIf CInt(txtInterval.Text) < 0 Then         MsgBox "You must enter a number greater than zero.", _                vbOKOnly + vbExclamation         Exit Sub     End If          'Make sure there is a directory server     If txtDirServer.Text = "" Then         MsgBox "You must enter a directory server!", _                vbOKOnly + vbExclamation         Exit Sub     End If          Me.MousePointer = vbHourglass          Dim strStartDate as String     Dim strEndDate as String     Dim strSMTPAddresses as String     'Figure out start and end date     strStartDate = monthStart.Value & " 12:00 AM"     strEndDate = monthEnd.Value & " 11:59 PM"          'Get the SMTP Addresses     If listUsers.ListCount > 0 Then         'Scroll through each user and separate with commas         Dim i         For i = 0 To listUsers.ListCount - 1             If i = 0 Then                 strSMTPAddresses = listUsers.List(i)             Else                 strSMTPAddresses = strSMTPAddresses & ", " & _                                    listUsers.List(i)             End If         Next     Else         MsgBox "You must enter users in order to query the server!", _                vbOKOnly + vbExclamation         Me.MousePointer = vbNormal         Exit Sub     End If          'Get the Response     strServerResponse = mSoapClient.GetFreeBusy(txtDirServer.Text, _                         strSMTPAddresses, strStartDate, strEndDate, _                         txtInterval.Text)          'Loop through the response and add it to the listbox     Dim arrResponse     arrResponse = Split(strServerResponse, ",")     For i = LBound(arrResponse) To UBound(arrResponse)         listResponse.AddItem arrResponse(i)     Next          Me.MousePointer = vbDefault     Exit Sub      ErrorHandler:          Me.MousePointer = vbDefault     If mSoapClient.faultstring <> "" Then         MsgBox "Could not refresh application. " & _                mSoapClient.faultstring, vbExclamation     Else         MsgBox "Could not refresh application. " & Err.Description     End If          Err.Clear End Sub 



Programming Microsoft Outlook and Microsoft Exchange 2003
Programming MicrosoftВ® OutlookВ® and Microsoft Exchange 2003, Third Edition (Pro-Developer)
ISBN: 0735614644
EAN: 2147483647
Year: 2003
Pages: 227
Authors: Thomas Rizzo

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