Building a Web Service

Building a Web Service

With all the daily decisions Visual Basic .NET programmers have to make, wouldn't it be helpful if there were an oracle of sorts we could turn to for sage development advice? If there were a Web service we could query for answers to our thorny problems, life would be so much simpler. So, let's create such a Web service for the betterment of all.

Start a new project and select ASP.NET Web Service. Name the project MagicEightBall. The New Project dialog box for our Web service is shown in Figure 13-24.

Figure 13-24

Create an ASP.NET Web Service project named MagicEightBall.

You'll be presented with a blank designer screen with the Service1.asmx.vb tab. Right-click the designer, and select Properties. Change the name from Service1 to Magic8Ball. This change will also change the name of the class in the code-behind from Service1 to Magic8Ball.

Bring up the Solution Explorer, and then right-click the Service1.asmx file. Rename the file Magic8.asmx. Right-click the designer again, and then select View Code to bring up the code window. Next change the URL to http://www.solidstatesoftware.com/webservices/ in the code before the class declaration. This statement provides a unique namespace for our Web service. The code should look like this:

<System.Web.Services.WebService(Namespace:= _ "http://www.solidstatesoftware.com/webservices/")> Public Class Magic8Ball Inherits System.Web.Services.WebService

Add the following code to the template:

Private possibleFutures() As String = _ {"The answer is unclear", _ "Uncertain at this time", _ "I have no idea", _ "Absolutely yes!", _ "Ask again later", _ "Emphatically No!", _ "Buy Microsoft short"} <WebMethod(Description:="Provides an answer")> _ Public Function getFuture() As String Dim rndRandom As System.Random = New System.Random() Dim iLower = possibleFutures.GetLowerBound(0) Dim iUpper = possibleFutures.GetUpperBound(0) Return possibleFutures(rndRandom.Next(iLower, iUpper)) End Function <WebMethod(Description:="Ask me a question")> _ Public Function getAnswer(ByVal Question As String) As String Dim rndRandom As System.Random = New System.Random() Dim iLower = possibleFutures.GetLowerBound(0) Dim iUpper = possibleFutures.GetUpperBound(0) Dim sAnswer As String sAnswer = Question & "? " & _ possibleFutures(rndRandom.Next(iLower, iUpper)) Return sAnswer End Function

The first member is a class-level array of strings, named possibleFutures. This array is private so that it can't be seen from outside the Web service. Next are two Web methods, getFuture and getAnswer. By prefacing each with the <WebMethod()> directive, we expose both of these methods to the outside world. The templates for the Web methods will show WebMethod(). By adding the description, users querying your Web service can see a useful message showing what each method is used for. Also notice that we used Question as the parameter for the getAnswer method instead of sQuestion. We used this name because Question will show up when our service is queried, making it crystal clear what the purpose of the method is. We keep our Web service simple, but just simple enough to provide sage advice to anyone who cares to query for it.

The first Web method, getFuture, returns an answer. The second, getAnswer, takes a specific question from the user and appends the answer. As you can see, we generate a random number between 0 and the number of entries in the possibleFutures array. A random response will be returned to the client using our service. If you want any helper functions, simply make them private so that they can't be seen by the outside world. We won't spend any more time on these methods because they should be very familiar by now.

Run the Program

Web services have no visual interface; they simply expose methods. Without writing any additional code, the screen shot shown in Figure 13-25 is displayed, showing the name of the Web service and the two services it currently offers.

Figure 13-25

The MagicEightBall application in action.

Click on getFuture to see information about the method along with a button you can click to invoke the method, shown in Figure 13-26. In addition, a sample SOAP request and response are provided.

Figure 13-26

Information about the getFuture method.

Click the Invoke button. A new browser window is displayed with the XML formatted response from the Magic8Ball Web service. We can see that an example answer is "Uncertain at this time." This text is what would be returned to a program on the Internet that invoked the getFuture method of our Web service.

<?xml version="1.0" encoding="utf-8" ?> <string xmlns="http://www.solidstatesoftware.com/webservices/"> Uncertain at this time</string> 

Close the second browser window, click the back button on the first browser, and click getAnswer. This method requires a string to be entered, so the name of the parameter, Question, is displayed as a prompt with a text box to enter our query. Now you can see why we used Question instead of the traditional sQuestion we would normally use when humans do not see parameters. Even though most programmers are human, they don't count in this context. Enter a question in the text box, and click Invoke, as shown in Figure 13-27.

Figure 13-27

Type in a question before you invoke the getAnswer method.

Another browser window is opened, and our answer is provided in XML. The service works as advertised. The question is displayed along with the answer.

<?xml version="1.0" encoding="utf-8" ?> <string xmlns="http://www.solidstatesoftware.com/webservices/"> Will Web services be the next big thing? Uncertain at this time</string> 

Now close the second browser window, click the back button in the first browser window, and click Service Description. A small portion of the WSDL for our Web service is shown in Figure 13-28.

Figure 13-28

A small portion of the WSDL for our Web service.

This WSDL file will be used to build a proxy class in a client that consumes our Web service.

Consuming the MagicEightBall Web Service

Start a new Windows application project named ConsumeEightBall. To keep things simple while illustrating each of the important concepts in this topic, our client will exercise both exposed Web methods of the MagicEightBall Web service. One button will retrieve an answer, and a second button will accept a question in the text box and return the question and answer. Our client is shown in Figure 13-29.

Figure 13-29

The ConsumeEightBall application in action.

One of the key questions you might have is, "Does a client actually execute methods on the Web service's Web server?" As you can imagine, doing that would be a serious security threat. Web masters don't want anyone to use their Web resources in a way that could do malicious damage to sensitive data, not to mention chewing up bandwidth. We also have to keep in mind that Web services are distributed applications. With distributed applications, we have to be concerned about the marshaling of data.

To get around these problems, we actually replicate the object behavior locally on the user's machine. In our example, we will replicate the MagicEightBall Web service functionality on the client's program. It sounds strange, but stay tuned. We do this replication by creating a proxy object to act on behalf of the original Web service. The proxy object has all the publicly available data interfaces that the original Web service does.

How do we get the publicly available data interface? Recall that we used the <WebMethod()> directive in our MagicEightBall service. Only Web methods will be replicated at the proxy object. This limitation protects our service from exposing sensitive business logic to malicious hackers at the client end. So we program to the proxy object in our program, and it takes care of sending the SOAP messages to and from the real Web service, as shown in Figure 13-30.

Figure 13-30

The proxy object takes care of sending the SOAP messages to and from the real Web service.

Building Our Web Services Client Program

Add two labels, two buttons, and a text box to the ConsumeEightBall default form, as shown in Figure 13-31.

Figure 13-31

Add these controls to the form.

Set the properties for each of the controls and the form as shown in Table 13-5.

Table 13-5  Properties for the ConsumeEightBall Controls

Object

Property

Value

Form1

Text

Magic 8 Ball Client

Label

Name

lblRetrieveAnswer

BorderStyle

Fixed3D

Text

""

Button

Name

btnRetrieve

Text

&Retrieve an Answer

Text box

Name

txtQuestion

Text

""

Label

Name

lblQuestion

Text

""

Button

Name

btnAskQuestion

Text

&Ask a Question

Adding a Proxy Class to Our Program

To access the MagicEightBall Web service, we have to add a proxy class. You can add a proxy through the command line with a program called Wsdl.exe, but this approach is pretty difficult. I won't cover it, but if you are interested, you can check out the online help. Instead, we will do it the easy way.

Choose Add Web Reference from the Project menu to bring up the Add Web Reference dialog box. Click Web References On Local Web Server to display all the .vsdisco files in the InetPub\wwwroot directories. Click the .vsdisco file for our MagicEightBall service, as shown in Figure 13-32.

Click View Contract at the right side of the Add Web Reference dialog box to examine the XML formatted .disco discovery file. Click the Add Reference button to add this file to the project. Now take a look at the Solution Explorer. Notice in Figure 13-33 that the Web References folder contains the WSDL file of our Web service. This file is what's used to create the proxy that our program will use.

Figure 13-32

Click the .vsdisco file for our MagicEightBall service.

Figure 13-33

The Web References folder contains the WSDL file of our Web service.

Adding Code to Get Our Magic Eight Ball Answers

First right-click the form and choose View Code. Next add the Imports statement that will reference the local host folder in our Solution Explorer. This statement gives us the reference to the proxy class that was automatically built for us.

Imports ConsumeEightBall.localhost

Now add the code for the two buttons.

Private Sub btnRetrieve_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnRetrieve.Click Dim Magic8 As New localhost.Magic8Ball() lblRetrieveAnswer.Text = Magic8.getFuture End Sub Private Sub btnAskQuestion_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAskQuestion.Click Dim Magic8 As New localhost.Magic8Ball() If (txtQuestion.Text.Length < 2) Then MessageBox.Show("Please enter a question to submit.", _ "Magic 8 Ball Client", MessageBoxButtons.OK, _ MessageBoxIcon.Question) Else lblQuestion.Text = Magic8.getAnswer(txtQuestion.Text) End If End Sub

As you can see, all we have to do is create a reference to the Magic8Ball proxy that we just added. In both procedures, we created a local variable, Magic8, that is a new instance of the Magic8Ball proxy class. When the first button is clicked, we simply display the answer from the getFuture Web method, and when the second button is clicked, we pass in a question from the text box to the getAnswer Web method. As you can see, we simply have to get a reference to the proxy class Magic8Ball, as we would from any other class we might use from the .NET Framework or build ourselves. Then we can reference it. What could be easier?



Coding Techniques for Microsoft Visual Basic. NET
Coding Techniques for Microsoft Visual Basic .NET
ISBN: 0735612544
EAN: 2147483647
Year: 2002
Pages: 123
Authors: John Connell

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