Returning User-Defined Types

I l @ ve RuBoard

Returning User -Defined Types

It is often necessary to return user-defined types from a method, such as employee or department. When doing so, the WebService serialization will create a generic representation of the data element to return to the client. It is important to understand that WebServices should be used to return data and not objects. Essentially, a memento should be returned rather than trying to instantiate an object and attempt distributed reference counts.

A memento represents the current state of an object or the data necessary to describe an object. In the case of an employee, the basic information such as ID, name , department, and photo ID would represent the data associated with the employee.

The serialization services will serialize all public fields and public properties with GET assessors. To support de-serialization, the corresponding properties must also implement SET as well as GET within the accessory . Each field or property will be mapped to an XML element. This default behavior might serve well enough for simple services and serves as a starting point for using User Defined Types (UDT) within the context of a WebService.

Creating the Service

Start by creating a WebService named UDTWebService using VS.NET and rename the default Service1.asmx file to UDTService.asmx . As with all the WebServices created so far, the actual implementation will reside in the code-behind page.

The WebService will provide a method that will locate a person based on his or her last name; hence, the name of the method will be LocatePerson . Before implementing the method, it will be necessary to create a Person class that can be used to return the information to a WebService client (see Listing 4.4.8).

Listing 4.4.8 The UDTPerson Class
 1: namespace UDTWebService  2: {  3:     using System;  4:  5:     /// <summary>  6:     ///  The Person Class represents a basic UDT( User Defined Type )  7:     /// </summary>  8:     public class UDTPerson  9:     { 10:         ///Private Fields 11:         private string    m_FirstName; 12:         private string    m_LastName; 13: 14:         //Public Properties 15:         public string FirstName 16:         { 17:             get {  return m_FirstName; } 18:             set {  m_FirstName = value; } 19:         } 20: 21:         public string LastName 22:         { 23:             get {  return m_LastName; } 24:             set {  m_LastName = value; } 25:         } 26: 27: 28:         //Constructor(s) 29:         public UDTPerson( ) 30:         { 31:             //Default Constructor 32:         } 33: 34:         public UDTPerson( string FName, string LName ) 35:         { 36:             m_FirstName = FName; 37:             m_LastName = LName; 38:         } 39:     } 40: } 41: 

The UDTPerson class represents a basic C# class with no attributes applied to it. So how can it be serialized? Remember the Reflection API? This is the mechanism used to serialize this class. The WebService underpinning will use Reflection to scrape out information from the class and serialize that information. Again, only public fields or properties will be serialized.

With the implementation of UDTPerson completed, the next step is to add the LocatePerson method to the UDTService class. Update the UDTService class using the code appearing in Listing 4.4.9.

Listing 4.4.9 UDTService Source
 1: using System;  2: using System.Collections;  3: using System.ComponentModel;  4: using System.Data;  5: using System.Diagnostics;  6: using System.Web;  7: using System.Web.Services;  8:  9: namespace UDTWebService 10: { 11:     /// <summary> 12:     /// Summary description for UDTService. 13:     /// </summary> 14:     public class UDTService : System.Web.Services.WebService 15:     { 16:         private Hashtable    htPeople; 17: 18:         public UDTService() 19:         { 20:              //CODEGEN: This call is required by the ASP.NET Web Services Designer 21:              InitializeComponent(); 22: 23:              //Load the hashtable 24:              //Add some people to the hashtable 25:              htPeople = new Hashtable( ); 26:              htPeople.Add( "Weeks", new UDTPerson( "Richard", "Weeks" ) ); 27:              htPeople.Add( "Powell", new UDTPerson( "Bob", "Powell" ) ); 28:              htPeople.Add( "Martschenko", new UDTPerson( "Bill", "Martschenko" ) ); 29:              htPeople.Add( "Schumacher",  new UDTPerson( "Greg", "Schumacher" ) ); 30:              htPeople.Add( "Pitzer", new UDTPerson( "Jay", "Pitzer" ) ); 31: 32:         } 33: 34:         #region Component Designer generated code 35:         /// <summary> 36:         /// Required method for Designer support - do not modify 37:         /// the contents of this method with the code editor. 38:         /// </summary> 39:         private void InitializeComponent() 40:         { 41:         } 42:         #endregion 43: 44:         /// <summary> 45:         /// Clean up any resources being used. 46:         /// </summary> 47:         protected override void Dispose( bool disposing ) 48:         { 49:         } 50: 51:         [WebMethod] 52:          public UDTPerson LocatePerson( string LastName ) { 53: 54:             try { 55:                 return (UDTPerson)htPeople[ LastName ]; 56:             }  catch( Exception ) { 57:             } 58:             return null; 59:         } 60:     } 61: } 

Rather than retrieving from a database, this example creates a hash table to hold a few different people for whom to search. The LocatePerson method on line 52 takes the LastName as a string parameter. It is important to notice that the method looks no different than the WebMethod found in the EchoService . Because the default serialization mechanism handles the common case, you do not need to provide custom serialization code for the UDTPerson class.

Generating a Client Binding

Again, the WSDL.exe tool can be used to create the necessary client proxy class for invoking the LocatePerson method. Along with the proxy class, WSDL.exe will generate a simple class that represents the UDTPerson return type. The reason for this is that most users of your WebService will not have access to the code behind the service. Instead, they will have to rely on the WSDL description of the site to create the necessary client code to invoke any given service. Listing 4.4.10 shows the generated code produced by the WSDL.exe tool for the UDTService .

Listing 4.4.10 UDTService Proxy Code
 1: //------------------------------------------------------------------------  2: // <autogenerated>  3: //     This code was generated by a tool.  4: //     Runtime Version: 1.0.2914.11  5: //  6: //     Changes to this file may cause incorrect behavior and will be lost if  7: //     the code is regenerated.  8: // </autogenerated>  9: //------------------------------------------------------------------------ 10: 11: // 12: // This source code was auto-generated by wsdl, Version=1.0.2914.11. 13: // 14: using System.Diagnostics; 15: using System.Xml.Serialization; 16: using System; 17: using System.Web.Services.Protocols; 18: using System.Web.Services; 19: 20: 21: [System.Web.Services.WebServiceBindingAttribute(Name="UDTServiceSoap", graphics/ccc.gif Namespace="http://tempuri.org/")] 22: public class UDTService : System.Web.Services.Protocols.SoapHttpClientProtocol { 23: 24:     [System.Diagnostics.DebuggerStepThroughAttribute()] 25:     public UDTService() { 26:         this.Url = "http://localhost/UDTWebService/UDTService.asmx"; 27:     } 28: 29:     [System.Diagnostics.DebuggerStepThroughAttribute()] 30:     [System.Web.Services.Protocols.SoapDocumentMethodAttribute ("http://tempuri.org/ graphics/ccc.gif LocatePerson",  Use=System.Web.Services.Description.SoapBindingUse.Literal, graphics/ccc.gif ParameterStyle=System.Web.Services.Protocols. SoapParameterStyle.Wrapped)] 31:     public UDTPerson LocatePerson(string LastName) { 32:         object[] results = this.Invoke("LocatePerson", new object[] { 33:                     LastName} ); 34:         return ((UDTPerson)(results[0])); 35:     } 36: 37:     [System.Diagnostics.DebuggerStepThroughAttribute()] 38:     public System.IAsyncResult BeginLocatePerson(string LastName, graphics/ccc.gif System.AsyncCallback callback, object asyncState) { 39:         return this.BeginInvoke("LocatePerson", new object[] { 40:                     LastName} , callback, asyncState); 41:     } 42: 43:     [System.Diagnostics.DebuggerStepThroughAttribute()] 44:     public UDTPerson EndLocatePerson(System.IAsyncResult asyncResult) { 45:         object[] results = this.EndInvoke(asyncResult); 46:         return ((UDTPerson)(results[0])); 47:     } 48: } 49: 50: public class UDTPerson { 51: 52:     public string FirstName; 53: 54:     public string LastName; 55: } 

The WSDL.exe -generated code is basically the same as seen before; the new addition to notice is the UDTPerson class that was generated. Notice that the FirstName and LastName attributes are created as public fields rather than private fields. WSDL.exe has no way of knowing the actual implementation of UDTPerson as it exists on the server; instead, WSDL.exe must utilize the information found in the wsdl document to construct the proxy and referenced types.

Invoking UDTService.LocatePerson from Internet Explorer will produce an XML return and display it in the browser, as shown in Figure 4.4.8. This XML represents the return message from the WebService. Take a minute to study how the XML maps to the UDTPerson class created by the WSDL.exe tool.

Figure 4.4.8. The XML result from LocatePerson .

graphics/0404fig08.gif

I l @ ve RuBoard


C# and the .NET Framework. The C++ Perspective
C# and the .NET Framework
ISBN: 067232153X
EAN: 2147483647
Year: 2001
Pages: 204

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