Deitel & Associates, Inc. Logo

Back to www.deitel.com
digg.png delicious.png blinkit.png furl.png
Visual C# 2005 How to Program, 2/e
Visual C# 2005 How to Program, 2/e

ISBN:
0-13-152523-9
© 2006
pages: 1535

Order
Amazon logo

[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.)
1   // Fig. 22.9: HugeInteger.cs
2   // HugeInteger Web service performs operations on large integers.
3   using System;
4   using System.Web;
5   using System.Web.Services;
6   using System.Web.Services.Protocols;
7   
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
13   {
14      private const int MAXIMUM = 100; // maximum number of digits
15      public int[] number; // array representing the huge integer
16   
17      // default constructor
18      public HugeInteger()
19      {
20         number = new int[ MAXIMUM ];
21      } // end default constructor
22   
23      // indexer that accepts an integer parameter
24      public int this[ int index ]
25      {
26         get
27         {
28            return number[ index ];
29         } // end get
30   
31         set
32         {
33            number[ index ] = value;
34         } // end set
35      } // end indexer
36   
37      // returns string representation of HugeInteger
38      public override string ToString()
39      {
40         string returnString = "";
41   
42         foreach ( int i in number )
43            returnString = i + returnString;
44   
45         return returnString;
46      } // end method ToString
47   
48      // creates HugeInteger based on argument
49      public static HugeInteger FromString( string value )
50      {
51         // create temporary HugeInteger to be returned by the method
52         HugeInteger parsedInteger = new HugeInteger();
53   
54         for ( int i = 0 ; i < value.Length; i++ )
55            parsedInteger[ i ] = Int32.Parse(
56               value[ value.Length - i - 1 ].ToString() );
57   
58         return parsedInteger;
59      } // end method FromString
60   
61      // WebMethod that adds integers represented by the string arguments
62      [ WebMethod( Description = "Adds two huge integers." ) ]
63      public string Add( string first, string second )
64      {
65         int carry = 0;
66         HugeInteger operand1 = HugeInteger.FromString( first );
67         HugeInteger operand2 = HugeInteger.FromString( second );
68         HugeInteger result = new HugeInteger(); // stores result of addition
69   
70         // perform addition algorithm for each digit
71         for ( int i = 0; i < MAXIMUM; i++ )
72         {
73            // add two digits in same column,
74            // result is their sum plus carry from
75            // previous operation modulo 10
76            result[ i ] =
77               ( operand1[ i ] + operand2[ i ] + carry ) % 10;
78   
79            // set carry to remainder of dividing sums of two digits by 10
80            carry = ( operand1[ i ] + operand2[ i ] + carry ) / 10;
81         } // end for
82   
83         return result.ToString();
84      } // end method Add
85   
86      // WebMethod that subtracts integers
87      // represented by the string arguments
88      [ WebMethod( Description = "Subtracts two huge integers." ) ]
89      public string Subtract( string first, string second )
90      {
91         HugeInteger operand1 = HugeInteger.FromString( first );
92         HugeInteger operand2 = HugeInteger.FromString( second );
93         HugeInteger result = new HugeInteger();
94   
95         // subtract bottom digit from top digit
96         for ( int i = 0; i < MAXIMUM; i++ )
97         {
98            // if top digit is smaller than bottom digit we need to borrow
99            if ( operand1[ i ] < operand2[ i ] )
100               Borrow( operand1, i );
101   
102               // subtract bottom from top
103               result[ i ] = operand1[ i ] - operand2[ i ];
104            } // end for
105   
106            return result.ToString();
107         } // end method Subtract
108   
109      // borrow 1 from next digit
110      private void Borrow( HugeInteger hugeInteger, int place )
111      {
112         // if no place to borrow from, signal problem
113         if ( place >= MAXIMUM - 1 )
114            throw new ArgumentException();
115   
116         // otherwise if next digit is zero, borrow from column to left
117         else if ( hugeInteger[ place + 1 ] == 0 )
118            Borrow( hugeInteger, place + 1 );
119   
120         // add ten to current place because we borrowed and subtract
121         // one from previous digit--this is the digit we borrowed from
122         hugeInteger[ place ] += 10;
123         hugeInteger[ place + 1 ]--;
124      } // end method Borrow
125   
126      // WebMethod that returns true if first integer is bigger than second
127      [ WebMethod( Description = "Determines whether the first integer is " +
128         "larger than the second integer." ) ]
129      public bool Bigger( string first, string second )
130      {
131         char[] zeros = { '0' };
132   
133         try
134         {
135            // if elimination of all zeros from result
136            // of subtraction is an empty string,
137            // numbers are equal, so return false, otherwise return true
138            if ( Subtract( first, second ).Trim( zeros ) == "" )
139               return false;
140            else
141               return true;
142         } // end try
143         // if ArgumentException occurs,
144         // first number was smaller, so return false
145         catch ( ArgumentException exception )
146         {
147            return false;
148         } // end catch
149      } // end method Bigger
150   
151      // WebMethod returns true if first integer is smaller than second
152      [ WebMethod( Description = "Determines whether the first integer " +
153         "is smaller than the second integer." ) ]
154      public bool Smaller( string first, string second )
155      {
156      // if second is bigger than first, then first is smaller than second
157         return Bigger( second, first );
158      } // end method Smaller
159   
160      // WebMethod that returns true if two integers are equal
161      [ WebMethod( Description = "Determines whether the first integer " +
162         "is equal to the second integer." ) ]
163      public bool EqualTo( string first, string second )
164      {
165      // if either first is bigger than second,
166      // or first is smaller than second, they are not equal
167      if ( Bigger( first, second ) || Smaller( first, second ) )
168         return false;
169      else
170         return true;
171      } // end method EqualTo
172   } // end class HugeInteger
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.
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 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).
 
Page 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

Tutorial Index