Introduction
This article is about using a web service to gather remote program version numbers. The problem was that many customers were running multiple versions of our product. We had no idea of what version they had and sometimes neither did they when they called for support. Since the customers were allowed to run a production version, a test version, and a development version of our products, we needed to know what version they were running in what circumstance. To retrieve the information that we needed, we used web services since the resulting data stream is nothing more than XML, which is plain text, and it can be transferred essentially without restriction over networks that have security measures in place to block other kinds of data. This code snippet shows the basic algorithms used in the process. Before installing, please read the Readme.txt file.
Background
There are many good books available to learn web services. You can also learn by reading and trying the articles at CodeProject or other sites. If you are unfamiliar with webservice
s, any place is a good place to start.
Using the Code
There are two pieces of code that will be shown. First, the web service since it will be called by the client. The pieces of information that we needed to gather are, Customer, Computer Name, Place, Product, Version, and Date. The information was gathered during the install and saved to a config file. With this information, we could determine what each customer
had for each product
installed. To store the information, I used Access, but you could just as easily use any other database. When the request came in, I wanted to see if the same pieces of information had already come in. If so, then all that was needed was to update the date. This way, we could run a report for each customer
to see what versions of the product
s they were running when they called. Old dates for customer
s showed that the server is no longer being used. This could happen when a server dies.
To start, I created a web service project which just had the hello world WebMethod
. I kept this method for testing down the road. I added a new method called SetCVersion
.
Public Function SetCVersion(ByVal Cusname As String, _
ByVal ComputerName As String, ByVal PlaceName As String,
ByVal ProductName As String, _
ByVal VersionNumber As String) As Boolean
Dim flg As Boolean
Dim cdb As CVersionDB
cdb = New CVersionDB()
cdb.Initialize()
flg = cdb.UpdateDB(Cusname, ComputerName, _
PlaceName, ProductName, VersionNumber)
SetCVersion = flg
End Function
As discussed, we wanted to track all of the information but only add or update based on the last time it was sent. I created a class to do the database updates; this separates the web service from the actual code that does the business logic. You should always do that since the code may be called from another component later. In fact, you should really create an assembly that does the work but for showing the concept, I did not do that.
The Initialize
method just gets the connection string from the config file. The UpdateDB
method does all of the work. Based on the passed information, we retrieve the records for the company, computer, and all of the other information. If we find a record, we update the date to show that it was used at that location. If we do not find a record, we add one. All we are trying to do is keep track of the products and their versions on each computer to help the customer
out when they call. For clarity, I removed the error logic for demonstration purposes, but it is in the downloadable code.
Public Function UpdateDB(ByVal Cusname As String, _
ByVal ComputerName As String, ByVal PlaceName As String, _
ByVal ProductName As String, _
ByVal VersionNumber As String) As Boolean
Dim cnn As OleDbConnection = New OleDbConnection(connstr)
Dim cmdVersion As New OleDbCommand
Dim cversionDA As New OleDbDataAdapter
Dim cversionDS As New DataSet
Dim selstr As String
Dim tblName As String = "CVersions"
Dim recordCnt As Integer
Dim recordPos As Integer
Dim retflag As Boolean
Dim AddType As Boolean
Dim NowTime As Date = Now
retflag = False
selstr = "SELECT * FROM CVersions Where CVCustomer = '" & _
Cusname & "' AND CVComputerName = '" & _
ComputerName & "' AND CVProduct = '" & _
ProductName & "' AND CVVersion = '" & _
VersionNumber & "' AND CVPlace = '" & PlaceName & "'"
Try
cmdVersion = cnn.CreateCommand
cmdVersion.CommandText = selstr
cversionDA.SelectCommand = cmdVersion
Dim cb As OleDbCommandBuilder = _
New OleDbCommandBuilder(cversionDA)
recordCnt = cversionDA.Fill(cversionDS, tblName)
recordPos = 0
AddType = False
If recordCnt = 0 Then
Dim myRow As DataRow
Try
AddType = True
myRow = cversionDS.Tables(tblName).NewRow()
cversionDS.Tables(tblName).Rows.Add(myRow)
recordCnt = cversionDS.Tables(tblName).Rows.Count
recordPos = recordCnt - 1
Catch ex As Exception
End Try
End If
cversionDS.Tables(tblName).Rows(recordPos)("CVCustomer") = Cusname
cversionDS.Tables(tblName).Rows(recordPos)("CVComputerName") = ComputerName
cversionDS.Tables(tblName).Rows(recordPos)("CVPlace") = PlaceName
cversionDS.Tables(tblName).Rows(recordPos)("CVProduct") = ProductName
cversionDS.Tables(tblName).Rows(recordPos)("CVVersion") = VersionNumber
cversionDS.Tables(tblName).Rows(recordPos)("CVDate") = NowTime
cversionDA.Update(cversionDS.Tables(tblName))
retflag = True
Dim lff As New LogFile
lff.Initialize()
If AddType Then
lff.write("Added record for cus = " & Cusname _
& " Computer = " & ComputerName & _
" Product = " & ProductName & _
" Version = " & VersionNumber & _
" Place = " & PlaceName)
Else
lff.write("Updated record for cus = " & _
Cusname & " Computer = " & ComputerName & _
" Product = " & ProductName & _
" Version = " & VersionNumber & _
" Place = " & PlaceName)
End If
Catch ex As Exception
End Try
cversionDS.Dispose()
cversionDA.Dispose()
UpdateDB = retflag
End Function
Now to test this without a client, just start the project. The initial page in the article should show up, that is the default page. Enter in the sample data and press the Invoke button. This will send in the data as if it came from a client. You can debug the entire web service this way. Before we put this in the public domain, we must set the namespace. By not having set one, the default of tempuri.org is used. Now this is fine for development purposes but it must be changed before you put this to use. Based on what your webservice will be doing, you should also check the different attributes that are available. Some will increase performance based on what you are doing. In a future article, we will explore the performance of this webservice
. Some of the attributes that are available are:
Property | Description |
BufferResponse | true /false - get or set if this webmethod should buffer the response it sends back |
CacheDuration | Allows you to get or set how long the buffered response is held for |
Description | Set a descriptive message about this webmethod |
EnableSession | true /false - get or set whether this webmethod supports sessions |
MessageName | Set the name of the method that users will use in their URL when calling it |
TransactionOption | Allows you to get or set whether this method will support transactions and in what capacity |
TypeID | Set a unique value if you subclass the ATTRIBUTE class |
The client is a VB form application that calls the web service. For testing purposes, I created two ways to call the web service. One interactive, and the other in a batch mode. I prompt for the URL so I can test from a remote machine and the local machine that the web service is running on. When you run the client program on a remote computer, just change localhost
to the machine name that the web service is running on.
Using the program in an interactive mode, we can now test a new company, computer and an update of a company, computer. If you enter information in for the first time, it should be an add. If you press the Send button again, it should be an update. An example of setting the URL in code is shown below for the batch mode. If the TargetURL
string
is empty, I use the string
from the config file. If the user has entered in another URL, I will use that one.
Private Sub Sendbatch()
Dim mycver As New localhost.CVersion()
Dim flg As Boolean
Dim ss As String
ss = txtURL.Text
If (ss = String.Empty) Then
mycver.Url() = ConfigurationSettings.AppSettings("URLStr")
Else
mycver.Url() = ss
End If
flg = mycver.SetCVersion("Customer1", "computer1", _
"place1-prod", "product1", "v1.1")
flg = mycver.SetCVersion("Customer1", "computer2", _
"place2-test", "product2", "v6.9")
flg = mycver.SetCVersion("Customer2", "computer1", _
"place1-prod", "product1", "v1.2")
flg = mycver.SetCVersion("Customer2", "computer2", _
"place2-test", "product2", "v7.0")
End Sub
These programs show the basic web service in use. From this, you should be able to create your own web service to do the tasks that you need to do.
Points of Interest
Some of the next things I plan to write about are using this web service to do performance testing. That is the main reason I left the helloworld
and byebye
world web methods in the service. One item you might have noticed is that anyone can send in the information since there is no security around the service. With the release of WS-Security or .NET 2.0, you will be able to include account information in the header of the message.
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.