22.7. User-Defined Types in Web ServicesThe Web methods we have demonstrated so far all received and returned primitive-type values. It is also possible to process user-defined typesknown as custom typesin a Web service. These types can be passed to or returned from Web methods. Web service clients also can use these user-defined types, because the proxy class created for the client contains the type definitions. This section presents an EquationGenerator Web service that generates random arithmetic equations of type Equation. The client is a math-tutoring application that inputs information about the mathematical question that the user wishes to attempt (addition, subtraction or multiplication) and the skill level of the user (1 specifies equations using numbers from 1 to 10, 2 specifies equations involving numbers from 10 to 100, and 3 specifies equations containing numbers from 100 to 1000). The Web service then generates an equation consisting of random numbers in the proper range. The client application receives the Equation and displays the sample question to the user in a Windows Form. Serialization of User-Defined TypesWe mentioned earlier that all types passed to and from Web services must be supported by SOAP. How, then, can SOAP support a type that is not even created yet? Custom types that are sent to or from a Web service are serialized, enabling them to be passed in XML format. This process is referred to as XML serialization. Requirements for User-Defined Types Used with Web MethodsClasses that are used to specify return types and parameter types for Web methods must meet several requirements:
Any data that is not serialized simply receives its default value (or the value provided by the default or parameterless constructor) when an object of the class is deserialized. Common Programming Error 22.3
Common Programming Error 22.4
Software Engineering Observation 22.1
Defining Class EquationWe define class Equation in Fig. 22.26. Lines 1529 define a constructor that takes three argumentstwo Integers representing the left and right operands and a String that represents the arithmetic operation to perform. The constructor sets the leftOperand, rightOperand and operationType instance variables, then calculates the appropriate result. The parameterless constructor (lines 1012) calls the three-argument constructor (lines 1529) and passes some default values. We do not use the parameterless constructor explicitly, but the XML serialization mechanism uses it when objects of this class are deserialized. Because we provide a constructor with parameters, we must explicitly define the parameterless constructor in this class so that objects of the class can be passed to or returned from Web methods. Figure 22.26. Class that stores equation information.
Class Equation defines properties LeftHandSide (lines 3847), RightHandSide (lines 5058), Left (lines 6169), Right (lines 7280), Result (lines 8492) and Operation (lines 95103). The client of the Web service does not need to modify the values of properties LeftHandSide and RightHandSide. However, recall that a property can be serialized only if it has both a Get and a Set accessorthis is true even if the Set accessor has an empty body. LeftHandSide (lines 3847) returns a String representing everything to the left of the equals (=) sign in the equation, and RightHandSide (lines 5058) returns a String representing everything to the right of the equals (=) sign. Left (lines 6169) returns the Integer to the left of the operator (known as the left operand), and Right (lines 7280) returns the Integer to the right of the operator (known as the right operand). Result (lines 8492) returns the solution to the equation, and Operation (lines 95103) returns the operator in the equation. The client in this case study does not use the RightHandSide property, but we included it in case future clients choose to use it. Method ToString (lines 3235) returns a String representation of the equation. Creating the EquationGenerator Web ServiceFigure 22.27 presents the EquationGenerator Web service, which creates random, customized Equations. This Web service contains only method GenerateEquation (lines 1632), which takes two parametersa String representing the mathematical operation (addition, subtraction or multiplication) and an Integer representing the difficulty level. Figure 22.27. Web service that generates random equations.
Testing the EquationGenerator Web ServiceFigure 22.28 shows the result of testing the EquationGenerator Web service. Note that the return value from our Web method is XML-encoded. However, this example differs from previous ones in that the XML specifies the values for all Public properties and data of the object that is being returned. The return object has been serialized in XML. The client's object class takes this XML and deserializes it into an object of class Equation, that can be used by the client. Figure 22.28. Returning an XML serialized object from a Web method.a) Invoking the GenerateEquation method to create a subtraction equation with numbers in the range 10100. b) XML encoded results of invoking the GenerateEquation method to create a subtraction equation with numbers in the range 10100. Note that an Equation object is not being passed between the Web service and the client. Rather, the information in the object is being sent as XML-encoded data. Clients created using .NET will take the information and create a new Equation object. Clients created on other platforms, however, may use the information differently. Readers creating clients on other platforms should check the Web services documentation for the specific platform they are using, to see how their clients may process custom types. Let's examine Web method GenerateEquation more closely. Lines 1819 of Fig. 22.27 define the upper and lower bounds for the random numbers that the method uses to generate an Equation. To set these limits, the program first calls Shared method Pow of class Maththis method raises its first argument to the power of its second argument. To calculate the value of maximum (the upper bound for any randomly generated numbers used to form an Equation), the program raises 10 to the power of the specified level argument (line 18). If level is 1, maximum is 10; if level is 2, maximum is 100; and if level is 3, maximum is 1000. Variable minimum's value is determined by raising 10 to a power one less than level (line 19). This calculates the smallest number with level digits. If level is 1, minimum is 1; if level is 2, minimum is 10; and if level is 3, minimum is 100. Lines 2527 create a new Equation object. The program calls Random method Next, which returns an Integer that is greater than or equal to the specified lower bound, but less than the specified upper bound. This method generates a left operand value that is greater than or equal to minimum but less than maximum (i.e., a number with level digits). The right operand is another random number with the same characteristics. Line 27 passes the String operation received by GenerateEquation to the Equation constructor. Line 29 returns the new Equation object to the client. Consuming the EquationGenerator Web ServiceThe MathTutor application (Fig. 22.29) calls the EquationGenerator Web service's GenerateEquation method to create an Equation object. The tutor then displays the left-hand side of the Equation and waits for user input. This example accesses classes Generator and Equation from the localhost namespaceboth are placed in this namespace by default when the proxy is generated. We declare variables of these types at lines 67. Line 7 also creates the Generator proxy. (Remember to add a Web reference to the EquationGeneratorWebService when you create this application. Figure 22.29. Math-tutoring application.
The math-tutoring application displays an equation and waits for the user to enter an answer. The default setting for the difficulty level is 1, but the user can change this by choosing a level from the RadioButtons in the GroupBox labeled Difficulty. Clicking any of the levels invokes the corresponding RadioButton's CheckedChanged event handler (lines 6987), which sets integer level to the level selected by the user. Although the default setting for the question type is Addition, the user also can change this by selecting one of the RadioButtons in the GroupBox labeled Operation. Doing so invokes the corresponding operation's event handlers in lines 4566, which assigns to String operation the symbol corresponding to the user's selection. Each event handler also updates the Text property of the Generate button to match the newly selected operation. Event handler btnGenerate_Click (lines 1020) invokes EquationGenerator method GenerateEquation (line 13). After receiving an Equation object from the Web service, the handler displays the left-hand side of the equation in lblQuestion (line 16) and enables btnOK so that the user can enter an answer. When the user clicks OK, btnOK_Click (lines 2342) checks whether the user provided the correct answer. |