Friday, August 25, 2006

SnTT: Web Services that Return Arrays

Be prepared: this is a longer post than usual. I wrote my first web service the other day. I was pretty excited the first time it actually worked (if you use Visual Studio to develop, always remember to save your work before you try to test your code!). So, aside from not saving my code before testing, the thing that slowed me down the most was figuring out how to handle the data that was coming back from the web service. I was sending back an array of a user-defined class and while I found a couple of good articles (IBM ID required on this one) on writing the web service so it would return what I wanted, I couldn't find anything about how to handle it in the calling program. But now that I have figured it out, I thought I'd share with the class.

This is a scaled down version of my web service code:


Public Class OneIssue
Public IssueNumber As String
Public IssueTitle As String
Public IssueDesc As String
Public IssueStatus As String
Public IssueTargetDate As String

Sub New

End Sub

Sub ReadValues(doc As NotesDocument)
IssueNumber = doc.IssueNumber(0)
IssueTitle = doc.IssueTitle(0)
IssueDesc = doc.IssueDesc(0)
IssueStatus = doc.TrackingDisposition(0)
IssueTargetDate = doc.TargetCompletion(0)
End Sub
End Class

Public Class IssueArray
Public MultipleIssues() As OneIssue
End Class

Public Class LOBReport
Private session As NotesSession
Private db As NotesDatabase

Sub New
Set session = New NotesSession
Set db = session.CurrentDatabase
End Sub

Public Function GetIssues(OrgUnit As String) As IssueArray
Dim dc As NotesDocumentCollection
Dim docIssue As NotesDocument
Dim view As NotesView
Dim x As Integer

Set GetIssues = New IssueArray
Set view = db.GetView("ByBusUnit")
Set dc = view.GetAllDocumentsByKey(OrgUnit)
If Not dc Is Nothing Then
x = 0
Set docIssue = dc.GetFirstDocument
While Not docIssue Is Nothing
Redim Preserve GetIssues.MultipleIssues(x)
Set GetIssues.MultipleIssues(x) = New OneIssue
GetIssues.MultipleIssues(x).ReadValues(docIssue)
x = x + 1
Set docIssue = dc.GetNextDocument(docIssue)
Wend
End If
End Function
End Class


This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.


Notice the classes at the top that define a single record of the class and the array of the first class. So what do you do with that in your calling program? My front end is a "proof of concept" at this point so I used Visual Studio.net to create a small Windows program. I won't get into the details of setting up your VS.net project and referencing the web service, but this is the code that calls the web service and handles the returned value:


Dim LOBReport As New webserverreference.LOBReportService
Dim retval As New webserverreference.ISSUEARRAY
Dim x As Integer
Dim y As webserverreference.ONEISSUE
Dim z As Integer
Dim strings(0) As String

TextBox1.Clear()
z = 0
retval = LOBReport.GETISSUES(ComboBox1.Text)
If Not retval.MULTIPLEISSUES Is Nothing Then
For x = 0 To UBound(retval.MULTIPLEISSUES)
y = retval.MULTIPLEISSUES(x)
ReDim Preserve strings(UBound(strings) + 6)
strings(z) = "Issue Number: " + y.ISSUENUMBER
strings(z + 1) = "Issue Title: " + y.ISSUETITLE
strings(z + 2) = "Issue Description: " + y.ISSUEDESC
strings(z + 3) = "Issue Status (LOB): " + y.ISSUESTATUS
strings(z + 4) = "Issue Target Completion: " + y.ISSUETARGETDATE
strings(z + 5) = ""
z = z + 6
Next
TextBox1.Lines = strings
Else
TextBox1.Text = "No records found, or user not authorized for business unit"
End If
End Sub


At the top, I define objects of the type defined in the classes in my web service, both the single item class and the array class. Then I loop through the array and process each item in it as an instance of my single item class.

Maybe the problems I had were because I haven't used Visual Basic much, but I hope putting this out here saves someone else some time.

Technorati:
Categories: Show-n-Tell Thursday_