22.4. Publishing and Consuming Web Services This section presents several examples of creating (also known as publishing) and using (also known as consuming) Web services. Recall that an application that consumes a Web service actually consists of two partsa proxy class representing the Web service and a client application that accesses the Web service via an instance of the proxy class. The instance of the proxy class passes a Web method's arguments from the client application to the Web service. When the Web method completes its task, the instance of the proxy class receives the result and parses it for the client application. Visual Basic 2005 and Visual Web Developer create these proxy classes for you. We demonstrate this momentarily. 22.4.1. Defining the HugeInteger Web Service Figure 22.9 presents the code-behind file for the HugeInteger Web service that you will build in Section 22.4.2. When creating Web services in Visual Web Developer, you work almost exclusively in the code-behind file. As we mentioned earlier, this Web service is designed to perform calculations with integers that have a maximum of 100 digits. Long variables cannot handle integers of this size (i.e., an overflow occurs). The Web service provides methods that take two "huge integers" (represented as Strings) and determine their sum, their difference, which one is larger or smaller and whether the two numbers are equal. You can think of these methods as services available to programmers of other applications via the Web (hence the term Web services). Any programmer can access this Web service, use the methods and thus avoid writing 170 lines of code. Figure 22.9. HugeInteger Web service. 1 ' Fig. 22.9: HugeInteger.vb 2 ' HugeInteger Web service performs operations on large integers. 3 Imports System.Web 4 Imports System.Web.Services 5 Imports System.Web.Services.Protocols 6 7 <WebService(Namespace:="http://www.deitel.com/", _ 8 Description:="A Web service that provides methods for" & _ 9 " manipulating large integer values")> _ 10 <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ 11 <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ 12 Public Class HugeInteger 13 Inherits System.Web.Services.WebService 14 15 Private Const MAXIMUM As Integer = 100 ' maximum number of digits 16 Public number As Integer() ' array representing the huge integer 17 18 ' default constructor 19 Public Sub New() 20 number = New Integer(MAXIMUM - 1) {} 21 End Sub ' New 22 23 ' property that accepts an integer parameter 24 Public Property Digit(ByVal index As Integer) As Integer 25 Get 26 Return number(index) 27 End Get 28 29 Set(ByVal Value As Integer) 30 number(index) = Value 31 End Set 32 End Property ' Digit 33 34 ' returns String representation of HugeInteger 35 Public Overrides Function ToString() As String 36 Dim returnString As String = "" 37 38 For Each digit As Integer In number 39 returnString = digit & returnString 40 Next 41 42 Return returnString 43 End Function ' ToString 44 45 ' creates HugeInteger based on argument 46 Public Shared Function FromString(ByVal value As String) As HugeInteger 47 ' create temporary HugeInteger to be returned by the method 48 Dim parsedInteger As New HugeInteger() 49 50 For i As Integer = 0 To value.Length - 1 51 parsedInteger.Digit(i) = Int32.Parse( _ 52 value.Chars(value.Length - i - 1).ToString()) 53 Next 54 55 Return parsedInteger 56 End Function ' FromString 57 58 ' WebMethod that adds integers represented by the String arguments 59 <WebMethod(Description:="Adds two huge integers.")> _ 60 Public Function Add(ByVal first As String, ByVal second As String) _ 61 As String 62 63 Dim carry As Integer = 0 64 Dim operand1 As HugeInteger = HugeInteger.FromString(first) 65 Dim operand2 As HugeInteger = HugeInteger.FromString(second) 66 Dim result As New HugeInteger() ' stores result of addition 67 68 ' perform addition algorithm for each digit 69 For i As Integer = 0 To MAXIMUM - 1 70 ' add two digits in same column 71 ' result is their sum, plus carry from 72 ' previous operation modulo 10 73 result.Digit(i) = _ 74 (operand1.Digit(i) + operand2.Digit(i) + carry) Mod 10 75 76 ' set carry to remainder of dividing sums of two digits by 10 77 carry = (operand1.Digit(i) + operand2.Digit(i) + carry) \ 10 78 Next 79 80 Return result.ToString() 81 End Function ' Add 82 83 ' WebMethod that subtracts integers represented by the String arguments 84 <WebMethod(Description:="Subtracts two huge integers.")> _ 85 Public Function Subtract(ByVal first As String, _ 86 ByVal second As String) As String 87 88 Dim operand1 As HugeInteger = HugeInteger.FromString(first) 89 Dim operand2 As HugeInteger = HugeInteger.FromString(second) 90 Dim result As New HugeInteger() 91 92 ' subtract bottom digit from top digit 93 For i As Integer = 0 To MAXIMUM - 1 94 ' if top digit is smaller than bottom digit we need to borrow 95 If operand1.Digit(i) < operand2.Digit(i) Then 96 Borrow(operand1, i) 97 End If 98 99 ' subtract bottom from top 100 result.Digit(i) = operand1.Digit(i) - operand2.Digit(i) 101 Next 102 103 Return result.ToString() 104 End Function ' Subtract 105 106 ' borrow 1 from next digit 107 Private Sub Borrow(ByVal hugeInteger As HugeInteger, _ 108 ByVal place As Integer) 109 110 ' if no place to borrow from, signal problem 111 If place >= MAXIMUM - 1 Then 112 Throw New ArgumentException() 113 114 ' otherwise if next digit is zero, borrow from column to left 115 ElseIf hugeInteger.Digit(place + 1) = 0 Then 116 Borrow(hugeInteger, place + 1) 117 End If 118 119 ' add ten to current place because we borrowed and subtract one from 120 ' previous digit--this is the digit we borrowed from 121 hugeInteger.Digit(place) += 10 122 hugeInteger.Digit(place + 1) -= 1 123 End Sub ' Borrow 124 125 ' WebMethod that returns true if first integer is bigger than second 126 <WebMethod(Description:="Determines whether the first integer is " & _ 127 "larger than the second integer.")> _ 128 Public Function Bigger(ByVal first As String, _ 129 ByVal second As String) As Boolean 130 131 Dim zeros() As Char = {"0"} 132 133 Try 134 ' if elimination of all zeros from result 135 ' of subtraction is an empty string, 136 ' numbers are equal, so return false, otherwise return true 137 If Subtract(first, second).Trim(zeros) = "" Then 138 Return False 139 Else 140 Return True 141 End If 142 Catch exception As ArgumentException 143 Return False ' first number was smaller, so return False 144 End Try 145 End Function ' Bigger 146 147 ' WebMethod returns True if first integer is smaller than second 148 <WebMethod(Description:="Determines whether the first integer " & _ 149 "is smaller than the second integer.")> _ 150 Public Function Smaller(ByVal first As String, _ 151 ByVal second As String) As Boolean 152 ' if second is bigger than first, then first is smaller than second 153 Return Bigger(second, first) 154 End Function ' Smaller 155 156 ' WebMethod that returns true if two integers are equal 157 <WebMethod(Description:="Determines whether the first integer " & _ 158 "is equal to the second integer.")> _ 159 Public Function EqualTo(ByVal first As String, _ 160 ByVal second As String) As Boolean 161 162 ' if either first is bigger than second, or first is 163 ' smaller than second, they are not equal 164 If Bigger(first, second) OrElse Smaller(first, second) Then 165 Return False 166 Else 167 Return True 168 End If 169 End Function ' EqualTo 170 End Class ' HugeInteger | Lines 79 contain a WebService attribute. Attaching this attribute to a Web service class declaration allows you to specify the Web service's namespace and description. Like an XML namespace (see Section 19.4), a Web service's namespace is used by client applications to differentiate that Web service from others available on the Web. Line 7 assigns http://www.deitel.com as the Web service's namespace using the WebService attribute's Namespace property. Lines 89 use the WebService attribute's Description property to describe the Web service's purposethis appears in the ASMX page (Fig. 22.2). Visual Web Developer places line 10 in all newly created Web services. This line indicates that the Web service conforms to the Basic Profile 1.1 (BP 1.1) developed by the Web Services Interoperability Organization (WS-I), a group dedicated to promoting interoperability among Web services developed on different platforms with different programming languages. BP 1.1 is a document that defines best practices for various aspects of Web service creation and consumption (www.WS-I.org). As we discussed in Section 22.2, the .NET environment hides many of these details from you. Setting the WebServiceBinding attribute's ConformsTo property to WsiProfiles.BasicProfile1_1 instructs Visual Web Developer to perform its "behind-the-scenes" work, such as generating WSDL and ASMX files, in conformance with the guidelines laid out in BP 1.1. For more information on Web services interoperabilty and the Basic Profile 1.1, visit the WS-I Web site at www.ws-i.org. By default, each new Web service class created in Visual Web Developer inherits from class System.Web.Services.WebService (line 13). Although a Web service need not derive from class WebService, this class provides members that are useful in determining information about the client and the Web service itself. Several methods in class HugeInteger are tagged with the WebMethod attribute (lines 59, 84, 126, 148 and 157), which exposes a method so that it can be called remotely. When this attribute is absent, the method is not accessible to clients that consume the Web service. Note that this attribute, like the WebService attribute, contains a Description property that allows the ASMX page to display information about the method (see these descriptions shown in Fig. 22.2). Common Programming Error 22.1 | Failing to expose a method as a Web method by declaring it with the WebMethod attribute prevents clients of the Web service from accessing the method. |
Portability Tip 22.1 | Specify a namespace for each Web service so that it can be uniquely identified by clients. In general, you should use your company's domain name as the Web service's namespace, since company domain names are guaranteed to be unique. |
Portability Tip 22.2 | Specify descriptions for a Web service and its Web methods so that the Web service's clients can view information about the service in the service's ASMX page. |
Common Programming Error 22.2 | No method with the WebMethod attribute can be declared Sharedfor a client to access a Web method, an instance of that Web service must exist. |
Lines 2432 define a Digit property, which provides access to any digit in a HugeInteger. Lines 5981 and 84104 define Web methods Add and Subtract, which perform addition and subtraction, respectively. Method Borrow (lines 107123) handles the case in which the digit that we are currently examining in the left operand is smaller than the corresponding digit in the right operand. For instance, when we subtract 19 from 32, we usually examine the numbers in the operands digit-by-digit, starting from the right. The number 2 is smaller than 9, so we add 10 to 2 (resulting in 12). After borrowing, we can subtract 9 from 12, resulting in 3 for the rightmost digit in the solution. We then subtract 1 from the 3 in 32the next digit to the left (i.e., the digit we borrowed from). This leaves a 2 in the tens place. The corresponding digit in the other operand is now the 1 in 19. Subtracting 1 from 2 yields 1, making the corresponding digit in the result 1. The final result, when the digits are put together, is 13. Method Borrow is the method that adds 10 to the appropriate digits and subtracts 1 from the digits to the left. This is a utility method that is not intended to be called remotely, so it is not qualified with attribute WebMethod. Recall that Fig. 22.2 presented a screen capture of the ASMX page HugeInteger.asmx for which the code-behind file HugeInteger.vb (Fig. 22.9) defines Web methods. A client application can invoke only the five methods listed in the screen capture in Fig. 22.2 (i.e., the methods qualified with the WebMethod attribute in Fig. 22.9). 22.4.2. Building a Web Service in Visual Web Developer We now show you how to create the HugeInteger Web service. In the following steps, you will create an ASP.NET Web Service project that executes on your computer's local IIS Web server. To create the HugeInteger Web service in Visual Web Developer, perform the following steps: Step 1. | Creating the Project
To begin, you must create a project of type ASP.NET Web Service. Select File > New Web Site... to display the New Web Site dialog (Fig. 22.10). Select ASP.NET Web Service in the Templates pane. Select HTTP from the Location drop-down list to indicate that the files should be placed on a Web server. By default, Visual Web Developer indicates that it will place the files on the local machine's IIS Web server in a virtual directory named WebSite (http://localhost/WebSite). Replace the name WebSite with HugeInteger for this example. Next, select Visual Basic from the Language drop-down list to indicate that you will use Visual Basic to build this Web service. Visual Web Developer places the Web service project's solution file (.sln) in the My Documents\Visual Studio 2005\Projects folder. If you do not have access to an IIS Web server to build and test the examples in this chapter, you can select File System from the Location drop-down list. In this case, Visual Web Developer will place your Web service's files on your local hard disk. You will then be able to test the Web service using Visual Web Developer's built-in Web server.
Figure 22.10. Creating an ASP.NET Web Service in Visual Web Developer. | | | Step 2. | Examining the Newly Created Project
After you create the project, the code-behind file Service.vb, which contains code for a simple Web service (Fig. 22.11), is displayed by default. If the code-behind file is not open, it can be opened by double clicking the file in the App_Code directory listed in the Solution Explorer. Visual Web Developer includes three Imports statements that are helpful for developing Web services (lines 13). By default, a new code-behind file defines a class named Service that is marked with the WebService and WebServiceBinding attributes (lines 56). The class contains a sample Web method named HelloWorld (lines 1114). This method is a placeholder that you will replace with your own method(s).
Figure 22.11. Code view of a Web service. | Step 3. | Modifying and Renaming the Code-Behind File
To create the HugeInteger Web service developed in this section, modify Service.vb by replacing all of the sample code provided by Visual Web Developer with all of the code from the HugeInteger code-behind file (Fig. 22.9). Then rename the file HugeInteger.vb (by right clicking the file in the Solution Explorer and choosing Rename). This code is provided in the examples directory for this chapter. You can download the examples from www.deitel.com/books/vbforprogrammers2/.
| | | Step 4. | Examining the ASMX File
The Solution Explorer lists a Service.asmx file in addition to the code-behind file. Recall from Fig. 22.2 that a Web service's ASMX page, when accessed through a Web browser, displays information about the Web service's methods and provides access to the Web service's WSDL information. However, if you open the ASMX file on disk, you will see that it actually contains only
<%@ WebService Language="vb" CodeBehind="~/App_Code/Service.vb"Class="Service"%> to indicate the programming language in which the Web service's code-behind file is written, the code-behind file's location and the class that defines the Web service. When you request the ASMX page through IIS, ASP.NET uses this information to generate the content displayed in the Web browser (i.e., the list of Web methods and their descriptions).
| Step 5. | Modifying the ASMX File
Whenever you change the name of the code-behind file or the name of the class that defines the Web service, you must modify the ASMX file accordingly. Thus, after defining class HugeInteger in the code-behind file HugeInteger.vb, modify the ASMX file to contain the lines
<%@ WebService Language="vb" CodeBehind="~/App_Code/HugeInteger.vb" Class="HugeInteger" %> Error-Prevention Tip 22.2 | Update the Web service's ASMX file appropriately whenever the name of a Web service's code-behind file or the class name changes. Visual Web Developer creates the ASMX file, but does not automatically update it when you make changes to other files in the project. | | Step 6. | Renaming the ASMX File
The final step in creating the HugeInteger Web service is to rename the ASMX file HugeInteger.asmx.
| 22.4.3. Deploying the HugeInteger Web Service The Web service is already deployed because we created the HugeInteger Web service directly on our computer's local IIS server. You can choose Build Web Site from the Build menu to ensure that the Web service compiles without errors. You can also test the Web service directly from Visual Web Developer by selecting Start Without Debugging from the Debug menu. This opens a browser window that contains the ASMX page shown in Fig. 22.2. Clicking the link for a particular HugeInteger Web service method displays a Web page like the one in Fig. 22.4 that allows you to test the method. Note that you can also access the Web service's ASMX page from your computer by typing the following URL in a Web browser http://localhost/HugeInteger/HugeInteger.asmx Accessing the HugeInteger Web Service's ASMX Page from Another Computer Eventually, you will want other clients to be able to access and use your Web service. If you deploy the Web service on an IIS Web server, a client can connect to that server to access the Web service with a URL of the form http://host/HugeInteger/HugeInteger.asmx where host is the hostname or IP address of the Web server. To access the Web service from another computer in your company's or school's local area network, you can replace host with the actual name of the computer on which IIS is running. If you have the Windows XP Service Pack 2 operating system on the computer running IIS, that computer may not allow requests from other computers by default. If you wish to allow other computers to connect to your computer's Web server, perform the following steps: | | 1. | Select Start > Control Panel to open your system's Control Panel window, then double click Windows Firewall to view the Windows Firewall settings dialog.
| 2. | In the Windows Firewall settings dialog, click the Advanced tab, select Local Area Connection (or your network connection's name, if it is different) in the Network Connection Settings list box and click the Settings... button to display the Advanced Settings dialog.
| 3. | In the Advanced Settings dialog, ensure that the checkbox for Web Server (HTTP) is checked to allow clients on other computers to submit requests to your computer's Web server.
| 4. | Click OK in the Advanced Settings dialog, then click OK in the Windows Firewall settings dialog.
| Accessing the HugeInteger Web Service's ASMX Page When the Web Service Executes in Visual Web Developer's Built-in Web Server Recall from Step 1 of Sections 22.4.2 that if you do not have access to an IIS server to deploy and test your Web service, you can create the Web service on your computer's hard disk and use Visual Web Developer's built-in Web server to test the Web service. In this case, when you select Start Without Debugging from the Debug menu, Visual Web Developer executes its built-in Web server, then opens a Web browser containing the Web service's ASMX page so that you can test the Web service. Web servers typically receive requests on port 80. To ensure that Visual Web Developer's built-in Web server does not conflict with another Web server running on your local computer, Visual Web Developer's Web server receives requests on a randomly selected port number. When a Web server receives requests on a port number other than port 80, the port number must be specified as part of the request. In this case, the URL to access the HugeInteger Web service's ASMX page would be of the form http://host:portNumber/HugeInteger/HugeInteger.asmx where host is the hostname or IP address of the computer on which Visual Web Developer's built-in Web server is running and portNumber is the specific port on which the Web server receives requests. You can see this port number in your Web browser's Address field when you test the Web service from Visual Web Developer. Unfortunately, Web services executed using Visual Web Developer's built-in server cannot be accessed over a network. 22.4.4. Creating a Client to Consume the HugeInteger Web Service Now that you have defined and deployed the Web service, let's see how to consume it from a client application. In this section, you'll create a Windows application as the client using Visual Basic 2005. After creating the client application, you'll add a proxy class to the project that allows the client to access the Web service. Recall that the proxy class (or proxy) is generated from the Web service's WSDL file and enables the client to call Web methods over the Internet. The proxy class handles all the details of communicating with the Web service. The proxy class is hidden from you by defaultyou can view it in the Solution Explorer by clicking the Show All Files button. The proxy class's purpose is to make clients think that they are calling the Web methods directly. This example demonstrates how to create a Web service client and generate a proxy class that allows the client to access the HugeInteger Web service. You will begin by creating a project and adding a Web reference to it. When you add the Web reference, the IDE will generate the appropriate proxy class. You will then create an instance of the proxy class and use it to call the Web service's methods. First, create a Windows application named UsingHugeIntegerWebService in Visual Basic 2005, then perform the following steps: Step 1. | Opening the Add Web Reference Dialog
Right click the project name in the Solution Explorer and select Add Web Reference... (Fig. 22.12).
Figure 22.12. Adding a Web service reference to a project. | | | Step 2. | Locating Web Services on Your Computer
In the Add Web Reference dialog that appears (Fig. 22.13), click Web services on the local machine to locate Web references stored on the IIS Web server on your local computer (http://localhost). This server's files are located at C:\Inetpub\wwwroot by default. Note that the Add Web Reference dialog allows you to search for Web services in several different locations. Many companies that provide Web services simply distribute the exact URLs at which their Web services can be accessed. For this reason, the Add Web Reference dialog also allows you to enter the specific URL of a Web service in the URL field.
Figure 22.13. Add Web Reference dialog. | | | Step 3. | Choosing the Web Service to Reference
Select the HugeInteger Web service from the list of available Web services (Fig. 22.14).
Figure 22.14. Web services located on localhost. | | | Step 4. | Adding the Web Reference
Add the Web reference by clicking the Add Reference button (Fig. 22.15).
Figure 22.15. Web reference selection and description. | Step 5. | Viewing the Web Reference in the Solution Explorer
The Solution Explorer (Fig. 22.16) should now contain a Web References folder with a node named after the domain name where the Web service is located. In this case, the name is localhost because we are using the local Web server. When we reference class HugeInteger in the client application, we will do so through the localhost namespace.
Figure 22.16. Solution Explorer after adding a Web reference to a project. | Notes on Creating a Client to Consume a Web Service The steps we just presented also apply to adding Web references to Web applications created in Visual Web Developer. We present a Web application that consumes a Web service in Section 22.6 When creating a client to consume a Web service, add the Web reference first so that Visual Basic 2005 (or Visual Web Developer) can recognize the Web service's class name. Once you add the Web reference to the client, it can access the Web service through an object of the proxy class. The proxy class (named HugeInteger) is located in namespace localhost, so you must use localhost.HugeInteger to reference this class. Although you must create an object of the proxy class to access the Web service, you do not need access to the proxy class's code. As we show in Section 22.4.5, you can invoke the proxy object's methods as if it were an object of the Web service class. The steps that we just described work well if you know the appropriate Web service reference. However, what if you are trying to locate a new Web service? A technology to facilitate this process is Universal Description, Discovery and Integration (UDDI). UDDI is an ongoing project to develop a set of specifications that define how Web services should be published so that programmers searching for Web services can find them. You can learn more about UDDI by visiting www.uddi.org and uddi.microsoft.com. You can also visit Web services directory sites like www.xmethods.net, which list many available Web services. 22.4.5. Consuming the HugeInteger Web Service The Windows Form in Fig. 22.17 uses the HugeInteger Web service to perform computations with positive integers up to 100 digits long. You are already familiar with Visual Basic applications that use Labels, TextBoxes and Buttons, so we focus our discussions on the Web services concepts in this chapter's applications. Figure 22.17. Using the HugeInteger Web service. 1 ' Fig. 22.17: UsingHugeIntegerWebService.vb 2 ' Using the HugeInteger Web Service. 3 Imports System.Web.Services.Protocols 4 5 Public Class UsingHugeIntegerWebService 6 ' declare a reference to Web service 7 Private remoteInteger As localhost.HugeInteger 8 9 ' character to trim from strings 10 Private zeros As Char() = New Char() {"0"c} 11 12 ' instantiates object to interact with Web service 13 Private Sub UsingHugeIntegerWebService_Load(ByVal sender As Object, _ 14 ByVal e As System.EventArgs) Handles Me.Load 15 ' instantiate remoteInteger 16 remoteInteger = New localhost.HugeInteger() 17 End Sub ' UsingHugeIntegerWebService_Load 18 19 ' adds two numbers input by user 20 Private Sub btnAdd_Click(ByVal sender As System.Object, _ 21 ByVal e As System.EventArgs) Handles btnAdd.Click 22 ' make sure numbers do not exceed 100 digits and that both 23 ' are not 100 digits long, which would result in overflow 24 If txtFirst.Text.Length > 100 Or txtSecond.Text.Length > 100 _ 25 Or (txtFirst.Text.Length = 100 And _ 26 txtSecond.Text.Length = 100) Then 27 MessageBox.Show( _ 28 "HugeIntegers must not be more than 100 digits" & _ 29 vbCrLf & "Both integers cannot be of length 100: " & _ 30 " this causes an overflow", "Error", _ 31 MessageBoxButtons.OK, MessageBoxIcon.Information) 32 Else 33 ' perform addition 34 lblResult.Text = remoteInteger.Add( _ 35 txtFirst.Text, txtSecond.Text).TrimStart(zeros) 36 End If 37 End Sub ' btnAdd_Click 38 39 ' subtracts two numbers input by user 40 Private Sub btnSubtract_Click(ByVal sender As System.Object, _ 41 ByVal e As System.EventArgs) Handles btnSubtract.Click 42 ' ensure that HugeIntegers do not exceed 100 digits 43 If Not NumbersTooBig(txtFirst.Text, txtSecond.Text) Then 44 ' perform subtraction 45 Try 46 Dim result As String = remoteInteger.Subtract( _ 47 txtFirst.Text, txtSecond.Text).TrimStart(zeros) 48 49 If result = "" Then 50 lblResult.Text = "0" 51 Else 52 lblResult.Text = result 53 End If 54 Catch exception As SoapException 55 ' if WebMethod throws an exception, 56 ' then first argument was smaller than second 57 MessageBox.Show( _ 58 "First argument was smaller than the second") 59 End Try 60 End If 61 End Sub ' btnSubtract_Click 62 63 ' determines whether first number input is larger than the second 64 Private Sub btnLarger_Click(ByVal sender As System.Object, _ 65 ByVal e As System.EventArgs) Handles btnLarger.Click 66 ' ensure that HugeIntegers do not exceed 100 digits 67 If Not NumbersTooBig(txtFirst.Text, txtSecond.Text) Then 68 ' call Web-service method to determine whether 69 ' first integer is larger than the second 70 If remoteInteger.Bigger(txtFirst.Text, txtSecond.Text) Then 71 lblResult.Text = txtFirst.Text.TrimStart(zeros) & _ 72 " is larger than " & txtSecond.Text.TrimStart(zeros) 73 Else 74 lblResult.Text = txtFirst.Text.TrimStart(zeros) & _ 75 " is not larger than " + txtSecond.Text.TrimStart(zeros) 76 End If 77 End If 78 End Sub ' btnLarger_Click 79 80 ' determines whether first number input is smaller than the second 81 Private Sub btnSmaller_Click(ByVal sender As System.Object, _ 82 ByVal e As System.EventArgs) Handles btnSmaller.Click 83 ' make sure HugeIntegers do not exceed 100 digits 84 If Not NumbersTooBig(txtFirst.Text, txtSecond.Text) Then 85 ' call Web-service method to determine if 86 ' first integer is smaller than second 87 If remoteInteger.Smaller(txtFirst.Text, txtSecond.Text) Then 88 lblResult.Text = txtFirst.Text.TrimStart(zeros) & _ 89 " is smaller than " + txtSecond.Text.TrimStart(zeros) 90 Else 91 lblResult.Text = txtFirst.Text.TrimStart(zeros) & _ 92 " is not smaller than " & txtSecond.Text.TrimStart(zeros) 93 End If 94 End If 95 End Sub ' btnSmaller_Click 96 97 ' determines whether the two numbers input are equal 98 Private Sub btnEqual_Click(ByVal sender As System.Object, _ 99 ByVal e As System.EventArgs) Handles btnEqual.Click 100 ' ensure that HugeIntegers do not exceed 100 digits 101 If Not NumbersTooBig(txtFirst.Text, txtSecond.Text) Then 102 ' call Web-service method to determine if integers are equal 103 If remoteInteger.EqualTo(txtFirst.Text, txtSecond.Text) Then 104 lblResult.Text = txtFirst.Text.TrimStart(zeros) & _ 105 " is equal to " & txtSecond.Text.TrimStart(zeros) 106 Else 107 lblResult.Text = txtFirst.Text.TrimStart(zeros) & _ 108 " is not equal to " & txtSecond.Text.TrimStart(zeros) 109 End If 110 End If 111 End Sub ' btnEqual_Click 112 113 ' determines whether numbers input by user are too big 114 Private Function NumbersTooBig(ByVal first As String, _ 115 ByVal second As String) As Boolean 116 ' display an error message if either number has too many digits 117 If (first.Length > 100) Or (second.Length > 100) Then 118 MessageBox.Show("HugeIntegers must be less than 100 digits", _ 119 "Error", MessageBoxButtons.OK, MessageBoxIcon.Information) 120 Return True 121 End If 122 123 Return False 124 End Function ' SizeCheck 125 End Class ' UsingHugeIntegerWebService | Line 7 declares variable remoteInteger of type localhost.HugeInteger. This variable is used in each of the application's event handlers to call methods of the HugeInteger Web service. The proxy object is created and assigned to this variable at line 16 in the Form's Load event handler. Lines 3435, 4647, 70, 87 and 103 in the various button event handlers invoke methods of the Web service. Note that each call is made on the local proxy object, which then communicates with the Web service on the client's behalf. If you downloaded the example from www.deitel.com/books/vbforprogrammers2, you might need to regenerate the proxy by removing the Web reference, then adding it again. To do so, right click localhost in the Web References folder in the Solution Explorer and select option Delete. Then follow the instructions in the preceding section to add the Web reference to the project. The user inputs two integers, each up to 100 digits long. Clicking a button causes the application to invoke a Web method to perform the appropriate task and return the result. Note that client application UsingHugeIntegerService cannot perform operations using 100-digit numbers directly. Instead the application creates String representations of these numbers and passes them as arguments to Web methods that handle such tasks for the client. It then uses the return value of each operation to display an appropriate message. Note that the application eliminates leading zeros in the numbers before displaying them by calling String method TrimStart. Like String method TRim (discussed in Chapter 16), TRimStart removes all occurrences of characters specified by a Char array (line 24) from the beginning of a String. |