[Note: This is an excerpt (Sections 22.1–22.4) of Chapter 22, Web Services, from our textbook Visual C# 2005 How to Program, 2/e. These articles may refer to other chapters or sections of the book that are not included here. Permission Information: Deitel, Harvey M. and Paul J., VISUAL C# 2005 HOW TO PROGRAM, 2/E, ©2005, pp.1164–1190. Electronically reproduced by permission of Pearson Education, Inc., Upper Saddle River, New Jersey.]
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 172 lines of code.
Fig. 22.9
HugeInteger Web service. (Part 1 of 4.)
|
|
|
|
|
|
|
|
5 using System.Web.Services;
|
6 using System.Web.Services.Protocols;
|
|
|
8 [ WebService( Namespace = "http://www.deitel.com/",
|
9 Description = "A Web service that provides methods for" +
|
10 " manipulating large integer values" ) ]
|
11 [ WebServiceBinding( ConformsTo = WsiProfiles.BasicProfile1_1 ) ]
|
12 public class HugeInteger : System.Web.Services.WebService
|
|
|
14 private const int MAXIMUM = 100;
|
|
|
|
|
|
|
|
|
|
|
20 number = new int[ MAXIMUM ];
|
|
|
|
|
|
|
24 public int this[ int index ]
|
|
|
|
|
|
|
28 return number[ index ];
|
|
|
|
|
|
|
|
|
33 number[ index ] = value;
|
|
|
|
|
|
|
|
|
38 public override string ToString()
|
|
|
40 string returnString = "";
|
|
|
42 foreach ( int i in number )
|
43 returnString = i + returnString;
|
|
|
|
|
|
|
|
|
|
|
49 public static HugeInteger FromString( string value )
|
|
|
|
|
52 HugeInteger parsedInteger = new HugeInteger();
|
|
|
54 for ( int i = 0 ; i < value.Length; i++ )
|
55 parsedInteger[ i ] = Int32.Parse(
|
56 value[ value.Length - i - 1 ].ToString() );
|
|
|
|
|
|
|
|
|
|
|
62 [ WebMethod( Description = "Adds two huge integers." ) ]
|
63 public string Add( string first, string second )
|
|
|
|
|
66 HugeInteger operand1 = HugeInteger.FromString( first );
|
67 HugeInteger operand2 = HugeInteger.FromString( second );
|
68 HugeInteger result = new HugeInteger();
|
|
|
|
|
71 for ( int i = 0; i < MAXIMUM; i++ )
|
|
|
|
|
|
|
|
|
|
|
77 ( operand1[ i ] + operand2[ i ] + carry ) % 10;
|
|
|
|
|
80 carry = ( operand1[ i ] + operand2[ i ] + carry ) / 10;
|
|
|
|
|
83 return result.ToString();
|
|
|
|
|
|
|
|
|
88 [ WebMethod( Description = "Subtracts two huge integers." ) ]
|
89 public string Subtract( string first, string second )
|
|
|
91 HugeInteger operand1 = HugeInteger.FromString( first );
|
92 HugeInteger operand2 = HugeInteger.FromString( second );
|
93 HugeInteger result = new HugeInteger();
|
|
|
|
|
96 for ( int i = 0; i < MAXIMUM; i++ )
|
|
|
|
|
99 if ( operand1[ i ] < operand2[ i ] )
|
100 Borrow( operand1, i );
|
|
|
|
|
103 result[ i ] = operand1[ i ] - operand2[ i ];
|
|
|
|
|
106 return result.ToString();
|
|
|
|
|
|
|
110 private void Borrow( HugeInteger hugeInteger, int place )
|
|
|
|
|
113 if ( place >= MAXIMUM - 1 )
|
114 throw new ArgumentException();
|
|
|
|
|
117 else if ( hugeInteger[ place + 1 ] == 0 )
|
118 Borrow( hugeInteger, place + 1 );
|
|
|
|
|
|
|
122 hugeInteger[ place ] += 10;
|
123 hugeInteger[ place + 1 ]--;
|
|
|
|
|
|
|
127 [ WebMethod( Description = "Determines whether the first integer is " +
|
128 "larger than the second integer." ) ]
|
129 public bool Bigger( string first, string second )
|
|
|
131 char[] zeros = { '0' };
|
|
|
|
|
|
|
|
|
|
|
|
|
138 if ( Subtract( first, second ).Trim( zeros ) == "" )
|
|
|
|
|
|
|
|
|
|
|
|
|
145 catch ( ArgumentException exception )
|
|
|
|
|
|
|
|
|
|
|
|
|
152 [ WebMethod( Description = "Determines whether the first integer " +
|
153 "is smaller than the second integer." ) ]
|
154 public bool Smaller( string first, string second )
|
|
|
|
|
157 return Bigger( second, first );
|
|
|
|
|
|
|
161 [ WebMethod( Description = "Determines whether the first integer " +
|
162 "is equal to the second integer." ) ]
|
163 public bool EqualTo( string first, string second )
|
|
|
|
|
|
|
167 if ( Bigger( first, second ) || Smaller( first, second ) )
|
|
|
|
|
|
|
|
|
|
|
Lines 8-10 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 8 assigns
http://www.deitel.com as the Web service's namespace using the
WebService attribute's
Namespace property. Lines 9-10 use the
WebService attribute's
Description property to describe the Web service's purpose-this appears in the ASMX page (Fig. 22.2).
Visual Web Developer places line 11 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 12). 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 62, 88, 127, 152 and 161), 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.
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.
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 static-for a client to access a Web method, an instance of that Web service must exist.
Lines 24-35 define an indexer, which enables us to access any digit in a
HugeInteger. Lines 62-84 and 88-107 define Web methods
Add and
Subtract, which perform addition and subtraction, respectively. Method
Borrow (lines 110-124) 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 32-the 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.cs (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).