Chapter 11

Return to programming challenge tips for all chapters

Updated 4/17/2007

Programming Challenge 2: ProjectTrackAw Web Service

When creating the solution for Challenge 2, we found it easiest to create an empty Visual Studio solution, and then insert three projects into it:

  • ProjectTrackAw Web service
  • ProjectTrackAw component, copied from the Chapter 6 examples
  • Windows Client application that consumes the Web service

Be sure to enter text into each WebMethod's Description property. Doing so will cause the description to display when users view your Web service in a browser. Here is a sample:

   <WebMethod(Description:="Returns a DataSet containing the " _
& "complete list of projects. The DataSet table returned by " _
& "this method is named Projects.")> _
Public Function GetAllProjects() As DataSet

Very little coding is required to create this Web service. Just create an instance of a DataSet, as shown on page 678. When you call a component method that returns a DataTable, just add the table to your DataSet. The WebMethod returns the DataSet. By the way, the second WebMethod in this assignment was changed from GetOneProject to the following:

  • GetProjectMembers: Returns a Dataset containing a list of members that belong to the project identified by the input project ID.

Create a Windows or Web client program that consumes your Web service. Our sample has a ToolStrip with a DropDown button named View that lists three choices: All projects, User Projects, and Project Members. Here's a sample:

 

Programming Challenge 3: Currency Conversion Web Service

This project requires you to enter a number of currency codes and conversion ratios and store them in a collection. Alternatively, you can use parallel arrays. The ratio associated with each currency type can be either multiplied by a foreign currency value to produce U.S. dollars. A similar opertion converts from dollars to other currency types. In any event, this is a simple project to complete.

 

Programming Challenge 4: Asynchronous Message Web Service

Be sure to allow yourself plenty of time to finish this project!

Start by creating a small database to hold the users, the messages, and the temporary session ID's. The session ID is the unique integer returned by the Login WebMethod. Here are the tables we used:

Users Table

Messages Table

Session Table

  • ID, int, identity, primary key
  • UserName, varchar(16)
  • Password, varchar(16
  • ID, int, identity, primary key
  • ReceiverId, int
  • SenderId, int
  • Body, text
  • WhenSent, datetime
  • userId, int
  • sessionId, int

Stored Procedures

We highly recommend creating stored procedures for this project. Here are the ones we created, which may be excessive, but they really came in handy. Each was tied to a method in one of the TableAdapters.

  • spAddMessage - add a row to the Messages table
  • spAddSessionEntry - add a row to the Session table
  • spFindUser - find a user, checking their username and password
  • spFindUserByName - find a user, given their username
  • spGetMessages - get all messages send to a particular user
  • spGetSessionId - given a userId, find the person's session ID
  • spGetUserId - given a session ID, find the peron's user ID
  • spRemoveSession - remove a given session ID from the Session table

TableAdapters

TableAdapters proved to be very useful in our solution program, using techniques described on page 678. The following image shows the adapters and methods we created. We will leave it to your imagination to figure out what each of these methods do.

Method Descriptions

When implementing the Web service, we decided to make a few small changes. First, we renamed the first parameter of the Login method to userName:

   Public Function Login(ByVal userName As String, _
ByVal password As String) As Integer

The parameters for the Logout, Send and GetMessages methods were also renamed for convenience:

   Public Function Send(ByVal sessionId As Integer, _
ByVal receiverName As String, ByVal message As String) As Boolean
   Public Function GetMessages(ByVal sessionId As Integer) As DataSet
   Public Sub Logout(ByVal sessionId As Integer)

Note: The session ID mentioned in the project description is a random integer generated by your own code. It is not the Session ID that Web servers and browsers use to communicate with each other.

Always enter text into the WebMethod's Description parameter. Doing so will cause the description to display in the Web interface used for testing your Web service:

   <WebMethod(Description:="Logs into the the message service " _
& "with a username and password. If the username is found, this " _
& "method returns a unique integer to be used in subsequent " _
& "transmissions. If the user is not found, this method returns 0.")> _
Public Function Login(ByVal userName As String, _
ByVal password As String) As Integer

Testing Your Web Service

It is a good idea to test your Web service interactively. Here, for example, is the test interface for the Login WebMethod.

After you enter a username and password, the Login method returns a unique session ID:

Then you can plug that session ID into the GetMessages WebMethod:

And so on. You can verify and test all of your Web methods.

Writing a Test Program

To really get the feel for how your Web Services works, you will have to write a test program. We wrote a Web application that lets the user log in, view their messages, send messages, and log out. Fortunately, the coding part of this program is extremely simple! Here's our login interface:

When the User clicks the Login button, they are given more options:

Clicking the Get messages button causes a GridView to display the contents of the Messages table:

(We created a View in the database that joins the Users and Messages tables to display the username of each message sender.)

If the user tries send a message to a nonexistent user, an error message is displayed:

When the user clicks the Log out button, the message panel, grid, and buttons are all hidden again:

The Logout method in the Web service also erases the user's session ID from the Session table.