This article offers a basic step-by-step instruction for getting a Web service on line using the Microsoft SOAP Toolkit 2.0 Gold Release. If you do not have this version, I suggest downloading and installing it before you read any further, including the samples (SOAP Toolkit 2.0 Gold Release samples). (See http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/MSDN-FILES/027/001/580/msdncompositedoc.xml) First I will explain the detailed steps I took to take one of their samples and produce a Web Service ready for publishing on line. Next I will take one of their sample clients and show you how to modify it in order to work with the Web Service that we created.
For this article I will create a very simple Web service that will accept credit card information and perform a standard MOD 10 (see http://www.aspfree.com/devlinks/search.asp?file404=mod;10) validation on the card. It accepts two parameters, the credit card number, and the credit card type. And it will return a string message indicating the result of the processing. For most of the Web interaction we are assuming that you are using Personal Web Server (PWS), and Internet Information Server (IIS) 4.0 or 5.0. Even though I have created this using IIS 5, it should work fine with the other Web servers. Under the Web root, I have created a simple structure for all of my Web services: webroot\webservices\public\ . This is where I place all of my service's listeners so that they can be consumed very easily.
Section 1: The Server -- Publishing the Web Service
We begin taking a look at the installed samples. On my server, they are located at C:\Program Files\MSSOAP\Samples\. For this article, I have chosen to use the "Calc" sample as the template.
Step 1 -- Making a Copy
In order to keep my samples untouched, I usually grab a copy of the samples that I work with and copy them to a new working location. Copy the directory C:\Program Files\MSSOAP\Samples\Calc\Service\SrSz\VbSrv\ to your working directory.
Step 2 -- Renaming and Deleting Unwanted Source Files
Take time now to rename the files that we copied to have a more appropriate name and delete two files I named my as follows:
Calc.cls rename to auth.cls
CalcSvcSrSzVb.dll delete
CalcSvcSrSzVb.vbp rename to cc.vbp
CalcSvcSrSzVb.vbw delete
Step 3 -- Open and Set Up the Project
Double click or open the Visual Basic Project (cc.vbp). Of course, this generates errors when it attempts to load the class file and does not find it. Just hit OK, and then click and drag auth.cls into the Project Explorer in Visual Basic (VB) 6.
Next, rename the project to "cc" and the class to "auth" to be consistent with the file names that we assigned to it.
Now we are ready to start coding.
Step 4 -- Editing the Samples to Fit Your Situation
If you scroll quickly through the code in the auth.cls file, you will notice that the key portion of the processing takes place in the Process method, including getting the available parameters and the method name, and doing the actual processing of the service. We will edit this to conform to this example.
Needed Variables:
Near the top of the Process method we see
Dim A As Double
Dim B As Double
Dim Answer As Double
Private Const WRAPPER_ELEMENT_NAMESPACE="http://tempuri.org/message/"
And since we will be using strings, we change these into the following:
Dim ccnumber As String
Dim cctype As String
Dim Answer As String
Method Name:
This section here is where we attempt to receive the method name, which the client has attempted to invoke.
MethodName = Reader.RPCStruct.baseName
If Err Then
ClientFault Response, "Cannot get method name. " & Err.Description
Exit Function
End If
This needs no change.
Parameters:
Basically, this section is needed to load up a parameter.
Set Parameter = Reader.RPCParameter("A")
If Parameter Is Nothing Then
ClientFault Response, "Cannot find parameter A. " & Err.Description
Exit Function
End If
A = CDbl(Parameter.Text)
If Err Then
ClientFault Response, "Parameter A not a Double value. " & Err.Description
Exit Function
End If
Notice the name of the Parameter ("A") and that it casts it to be a double. We can work with this to produce the following:
Set Parameter = Reader.RPCParameter("ccnumber")
If Parameter Is Nothing Then
ClientFault Response, "Cannot find parameter ccnumber. " & Err.Description
Exit Function
End If
ccnumber = CStr(Parameter.Text)
If Err Then
ClientFault Response, "Parameter ccnumber not a String value. " & Err.Description
Exit Function
End If
Set Parameter = Reader.RPCParameter("cctype")
If Parameter Is Nothing Then
ClientFault Response, "Cannot find parameter cctype. " & Err.Description
Exit Function
End If
cctype = CStr(Parameter.Text)
If Err Then
ClientFault Response, "Parameter cctype not a String value. " & Err.Description
Exit Function
End If
Next, what we need to do is add in our own business logic. The following is a fairly common routine that can be found anywhere on the Internet for performing Mod 10 verification on credit card numbers. Now, with this area you do have a few options.
The easiest (as used in this sample) method is to just simply copy and paste the entire business logic into this class and work with it from there.
You could also just add in your class file, and in the below Select Case construct, create an instance and call your custom class.
Or you can simply create an instance of your class that is registered on the server that this Web service is currently residing on, and perform the necessary calls for it to work.
The following is our code that we copied and pasted into the same class:
Public Function checkcc(ByVal ccnumber As String, ByVal cctype As String) As String
Dim cType, cclength, ccprefix, prefixes, lengths, Number As String
Dim prefixvalid, lengthvalid As Boolean
Dim prefix, length As Variant
Dim result, qsum, x, Sum As Long
Dim ch As Integer
cType = UCase(cctype)
Select Case cType
Case "V"
cclength = "13;16"
ccprefix = "4"
Case "M"
cclength = "16"
ccprefix = "51;52;53;54;55"
Case "A"
cclength = "15"
ccprefix = "34;37"
Case "C"
cclength = "14"
ccprefix = "300;301;302;303;304;305;36;38"
Case "D"
cclength = "16"
ccprefix = "6011"
Case "E"
cclength = "15"
ccprefix = "2014;2149"
Case "J"
cclength = "15;16"
ccprefix = "3;2131;1800"
Case Else
cclength = ""
ccprefix = ""
End Select
prefixes = Split(ccprefix, ";", -1)
lengths = Split(cclength, ";", -1)
Number = trimtodigits(ccnumber)
prefixvalid = False
lengthvalid = False
For Each prefix In prefixes
If InStr(Number, prefix) = 1 Then
prefixvalid = True
End If
Next
For Each length In lengths
If CStr(Len(Number)) = length Then
lengthvalid = True
End If
Next
result = 0
If Not prefixvalid Then
result = result + 1
End If
If Not lengthvalid Then
result = result + 2
End If
qsum = 0
For x = 1 To Len(Number)
ch = Mid(Number, Len(Number) - x + 1, 1)
'response.write ch
If x Mod 2 = 0 Then
Sum = 2 * CInt(ch)
qsum = qsum + (Sum Mod 10)
If Sum > 9 Then
qsum = qsum + 1
End If
Else
qsum = qsum + CInt(ch)
End If
Next
'response.write qsum
If qsum Mod 10 <> 0 Then
result = result + 4
End If
If cclength = "" Then
result = result + 8
End If
Select Case result
Case 0
checkcc = "Card is ok!"
Case 1
checkcc = "Wrong card type"
Case 2
checkcc = "Wrong length"
Case 3
checkcc = "Wrong length and card type"
Case 4
checkcc = "Wrong checksum"
Case 5
checkcc = "Wrong checksum and card type"
Case 6
checkcc = "Wrong checksum and length"
Case 7
checkcc = "Wrong checksum, length and card type"
Case 8
checkcc = "Unknown cardtype"
Case Else
checkcc = "General Failure"
End Select
End Function
Private Function trimtodigits(ByVal tstring As String)
'removes all chars except of 0-9
Dim s, ts As String
Dim x As Long
Dim ch As Integer
s = ""
ts = tstring
For x = 1 To Len(ts)
ch = Mid(ts, x, 1)
If Asc(ch) >= 48 And Asc(ch) <= 57 Then
s = s & ch
End If
Next
trimtodigits = s
End Function
So now we have all the needed requirements for the service. We know which method to call, and with the appropriate parameters. This section deals with determining the proper action to take when the object is invoked. We will need to modify the Web service Select Case construct in order to call the appropriate method.
Select Case MethodName
Case "checkcc"
Answer = checkcc(ccnumber, cctype)
Case Else
ClientFault Response, "Unknown method: """ & MethodName & """."
Exit Function
End Select
Step 5 -- Saving, Compiling, and Registering
Save your Project, and make the DLL. Make sure you rename it from the default to something more appropriate like "cc.auth.dll." You have a couple of options to register the DLL on your machine. For this article, I will be using Component Services on my Windows 2000 machine (for the purpose of this article, Microsoft Transaction Server {MTS} on Windows NT is the equivalent). A second alternative is using regsvr32 dllname. Imar Spaanjaars has allowed me to post his write-up about using Component Services (MTS) for recompiling a DLL. Please review it at http://www.aspfree.com/authors/robert/faq.asp?id=13.
Step 6 -- Using the SOAP Toolkit 2.0 Wizard
This is probably the easiest step of them all. When you installed the SOAP Toolkit it should have included the file C:\Program Files\MSSOAP\Binaries\wsdlgen.exe.
Run it and follow the simple steps in order to take your new Web
service on line. This wizard will automatically create a few files for you:
1. Hit Next.
2. Hit the "Select COM Object" button.
3. Find your COM Object.
NOTE: If you have exposed any other method in another COM, you must choose that COM Object here so that you expose that object's methods.
4. Hit Open.
5. In the Name box, type "ccauth" with no quotes.
6. Hit Next.
7. Since we wish to expose the "checkcc" method, make sure it is checked.
8. Hit Next.
9. For the listener URI, I have chosen to place these new files (the actual Web Service Listener) in my webroot\webservices\public\ folder, so I will put: http://localhost/webservices/public/ccauth/
10. Ensure that ASP Listener is chosen for the listener type.
11. For the XSD Schema Namespace double check that 2001 is chosen.
12. Hit Next .
13. UTF-8 is fine for this example.
14. As mentioned previously I have chosen to place these new files (the actual Web Service Listener) in my C:\Inetpub\wwwroot\webservices\public\ccauth\ folder. Using the "Select" button, choose the location for your service, and hit OK.
15. Finished!
Step 7: The ASP Listener
During Step 6, we chose to create an ASP Listener. This default listener that the toolkit creates uses the Application object to store an instance of Microsoft's Soap Server, and personally I don't like this idea. For some implementations, this is not even an option. This step will outline the steps required to cut down the default code into something that is not reliant on the Application object. Open up the listener (see c:\Inetpub\wwwroot\webservices\public\ccauth\ccauth.asp) and modify this section.
Option Explicit
On Error Resume Next
Response.ContentType = "text/xml"
Dim SoapServer
If Not Application("SoapServerInitialized") Then
Application.Lock
If Not Application("SoapServerInitialized") Then
Dim WSDLFilePath
Dim WSMLFilePath
WSDLFilePath = Server.MapPath("ccauth.wsdl")
WSMLFilePath = Server.MapPath("ccauth.wsml")
Set SoapServer = Server.CreateObject("MSSOAP.SoapServer")
If Err Then SendFault "Cannot create SoapServer object. " & Err.Description
SoapServer.Init WSDLFilePath, WSMLFilePath
If Err Then SendFault "SoapServer.Init failed. " & Err.Description
Set Application("ccauthServer") = SoapServer
Application("SoapServerInitialized") = True
End If
Application.UnLock
End If
Set SoapServer = Application("ccauthServer")
SoapServer.SoapInvoke Request, Response, ""
If Err Then SendFault "SoapServer.SoapInvoke failed. " & Err.Description
Change the above section of code to read as it does below:
Option Explicit
On Error Resume Next
Response.ContentType = "text/xml"
Dim WSDLFilePath, WSMLFilePath, SoapServer
'get full path of WSDL & WSML files
WSDLFilePath = Server.MapPath("ccauth.wsdl")
WSMLFilePath = Server.MapPath("ccauth.wsml")
'get an instance of the Soap Server
Set SoapServer = Server.CreateObject("MSSOAP.SoapServer")
'error check
If Err Then SendFault "Cannot create SoapServer object. " & Err.Description
'initialize the Soap Server
SoapServer.Init WSDLFilePath, WSMLFilePath
'invoke the service request
SoapServer.SoapInvoke Request, Response, ""
'check for error & report
If Err Then SendFault "SoapServer.SoapInvoke failed. " & Err.Description
Conclusion: The Server. Publishing the Web Service
This article shows the quickest way to get a Web service online, using the provided samples from Microsoft. You now have a working Web service on your machine that's ready to be consumed. In my next article, I will take a look at how we will consume this Web service with our Web Service Client.
About the Author
Robert Chartier has worked in the information technologies field for more than 7 years. While studying full time at college he began his career working as a software and hardware technician at the local college, supporting a user base of thousands of students and hundreds of instructors. Once his college days were finished he moved on to full-time studies in a University in the lower mainland of British Columbia, and landed a full-time job developing large projects for distribution on many platforms, mediums, and languages.
Next, he moved onto Stockgroup, where he was able to tap into the Internet development market on a larger and more focused scale. In his spare time he began writing and producing content for developer-specific sites focusing on Microsoft technologies (ASP, COM/COM+, etc..). He has also been a part of many open forums on cutting-edge technologies such as the .NET Framework, Web Services (SOAP), and has been invited to speak at large developer conferences and contribute to many technical publications.
His next step was to take a position with a large B2B training marketplace, Thinq.com. At Thinq he developed many tools, including a very comprehensive search engine with custom business rules for weighting, sorting, and analysis (COM+). This led him into strong development with beta versions of Commerce Server 2000 and BizTalk Server 2000.
His next opportunity included a large Internet development effort using technologies such as JSP (Java Beans, J2EE), Oracle, WebLogic, etc.
Stonebroom.ASP2XML(c) is an interface component designed to make building
applications that transport data in XML format much easier. It can be used
to automatically pass updates back to the original data source.
Right now the latest buzzword around town is AJAX. AJAX is an acronym for Asynchronous JavaScript and XML and is a method used to implement remote calling. The problem is that AJAX is only implemented in ASP.NET 2.0. This article will show you one way to implement remote calling without using AJAX or the XMLHttpRequest object. The technique outlined can even be used from classic ASP and is sufficient for most remote calling needs. [Read This Article][Top]
This article is the third and final installment of Alex Homer's series covering the new XML support in Microsoft SQL Server 2005. In it he covers updating the contents of xml columns, comparing traditional XML update techniques with XQuery, and using XQuery in a managed code stored procedure. [Read This Article][Top]
In the second part of his series on SQL Server 2005's new XML support, Alex Homer looks at extracting data from XML columns, comparing traditional XML data access approaches with XQuery, and combining XQuery and XSL-T.
[Read This Article][Top]
Microsoft SQL Server 2005 now offers great support for and close integration with XML as a data persistence format. In the first article of his series examining this new support, Alex Homer offers an overview of how SQL Server 2005 stores XML documents and schemas, examines how it supports querying and manipulating XML documents, and provides a simple test application that allows you to experiment with XQuery. [Read This Article][Top]
In the final article of his series on reading and writing XML in .NET 2.0, Alex Homer looks at how the updated XML document store objects XmlDocument, XmlDataDocument and PathDocument can be used to read, persist and write XML documents and fragments more easily and more efficiently than in .NET 1.x. [Read This Article][Top]
In the final article of his series on reading and writing XML in .NET 2.0, Alex Homer looks at how the updated XML document store objects XmlDocument, XmlDataDocument and PathDocument can be used to read, persist and write XML documents and fragments more easily and more efficiently than in .NET 1.x. [Read This Article][Top]
Alex Homer continues his series on reading and writing XML in .NET 2.0. In part one, we focused on the reading side of things, examining the XmlReader and XmlReaderSettings classes. In this article, we move on to look at the XmlWriter and XmlWriterSettings classes, and how they can be used to write XML documents and fragments more easily and more efficiently than in version 1.x of .NET.
[Read This Article][Top]
Alex Homer continues his series on reading and writing XML in .NET 2.0. In part one, we focused on the reading side of things, examining the XmlReader and XmlReaderSettings classes. In this article, we move on to look at the XmlWriter and XmlWriterSettings classes, and how they can be used to write XML documents and fragments more easily and more efficiently than in version 1.x of .NET. [Read This Article][Top]
In the first part of his series on reading and writing XML in .NET 2.0, Alex Homer discusses the XmlReader and XmlReaderSettings classes. The XmlReader exposes several useful new features and the all new XmlReaderSettings class makes it easy to generate single or multiple instances of an XmlReader with a range of useful properties. [Read This Article][Top]
In the first part of his series on reading and writing XML in .NET 2.0, Alex Homer discusses the XmlReader and XmlReaderSettings classes. The XmlReader exposes several useful new features and the all new XmlReaderSettings class makes it easy to generate single or multiple instances of an XmlReader with a range of useful properties. [Read This Article][Top]
Mailing List
Want to receive email when the next article is published? Just Click Here to sign up.