Hotel Broker Web Service

for RuBoard

The next step in the case study is to make the Customer and Hotel components of the Hotel Broker available as a Web Service. This Web Service is found in the HotelBrokerWebService subdirectory of the case study for this chapter. This Web Service will be used both by Acme's customers to make reservations as well as by administrators for maintenance tasks associated with the Hotel Broker.

The proxy classes themselves are built into a proxies assembly. Two batch files that can be used to create the proxy classes and build the assembly are located in the WebServiceProxies subdirectory of the case study.

In the HotelBrokerAdministration subdirectory you will find a version of the admin program that uses the proxies assembly instead of the Customer and Hotel assemblies. In the AcmeWeb2 subdirectory for the case study you will find a version of AcmeLib that references the proxies assembly instead of the Customer and Hotel assemblies. All references to the Customer and Hotel components in the Acme reservation Web page and HotelBrokerAdministration programs have been removed.

Since at this stage in the book you have a lot of experience with .NET, we do not spell out the details of building the various pieces of the case study. Please consult the file readme.txt in the CaseStudy directory if you would like some pointers.

Customer Web Service

To implement the customer Web service we created a file, CustomerWebService.asmx , that uses the Customer component to implement the details of the Web Service:

 [WebService(Namespace=           "urn:uuid:10C14FCF-BF4A-477a-BFE7-41B9F2A4514E")]  class CustomerWebService  {    private Customers customers;    public CustomerWebService()    {      customers = new Customers("HotelBroker");    }    [WebMethod]    public int RegisterCustomer(string firstName,                       string lastName, string emailAddress)    {      int customerId;      customerId = customers.RegisterCustomer(firstName,                                    lastName, emailAddress);      return customerId;    }    [WebMethod]    public void UnregisterCustomer(int customerId)    {      customers.UnregisterCustomer(customerId);    }    [WebMethod]    [XmlInclude(typeof(CustomerListItem))]    public ArrayList GetCustomer(int customerId)    {      ArrayList ar;       ar = customers.GetCustomer(customerId);      return ar;    }    [WebMethod]    public void ChangeEmailAddress(int customerId,                                        string emailAddress)    {      customers.ChangeEmailAddress(customerId,                                              emailAddress);    }  } 

The only new attribute is XmlInclude , which allows the XmlSerializer used to create the SOAP protocol to serialize a custom type, in this case CustomerListItem . This attribute is found in the System.Xml.Serialization namespace. Nonetheless, if you examine the proxy class for this Web Service, which is found in the WebServiceProxies directory, you will see that GetCustomer proxy ( customerproxy.cs ) returns only an array of objects.

 public object[] GetCustomer(int customerId) 

Although the attribute instructs the serializer to save the custom type, the SOAP protocol understands only how to transmit a generic object type. So the AcmeLib code ( Acme.cs ) has to treat the return type as an object and then extract the custom type from it.

 object[] al = customers.GetCustomer                                 (hotelCustomerId);  foreach(CustomerListItem cust in al)  {    currentUser.HotelCustomerId = hotelCustomerId;    currentUser.FirstName = cust.FirstName;    currentUser.LastName = cust.LastName;    currentUser.EmailAddress = cust.EmailAddress;  } 

All the other ArrayLists in the Customer and Hotel Web Services are treated as arrays of objects where the appropriate type has to be extracted. Arrays that use types such as strings and integers, however, need no special treatment by the XmlSerializer.

For the HotelBroker Web Service, the Hotel assembly itself was modified to be a Web Service. The HotelWebService.asmx file has to make reference only to the HotelBroker class in the Hotel assembly, which is located in the bin subdirectory of the Web Service.

 <%@ WebService Language="C#"                class ="OI.NetCs.Acme.HotelBroker, Hotel" %> 

The code is the same as the previous version of the component except for addition of the necessary attributes to convert the code to a Web Service. Since Web Service names have to be unique, we had to use the MessageName property of the WebMethod attribute to give one of the overloaded GetHotels methods a unique name .

 [WebMethod(MessageName="GetAllHotels")]  [XmlInclude(typeof(HotelListItem))]  public ArrayList GetHotels() 

The code in Acme.cs is modified where necessary to handle the generic object[] arrays that are returned instead of the CLR specific ArrayList type.

Design Considerations

Network latency is a major performance consideration. Hence, the number of requests made over the network to a Web Service or a database should be minimized. In the HotelBroker Web Service, the reservations for a customer are kept in the dataset as a cache, so that only for database modifications does a database request have to be made. The same is true for tracking the hotels and cities, although there is a trade-off here, since an administrator might add a new hotel. However, that operation is not likely to occur during the relatively short time a customer is making a reservation. Of course, these types of data could be cached inside the Web form itself, so a call to the Web Service would be unnecessary.

HTTP is a stateless protocol and therefore so is SOAP. Minimizing state will help your applications and Web Services to scale better, because objects (such as database connections) can be pooled or reused much more easily, and less memory is required so that more resources are available to handle more requests. This means treating your Web Service objects as endpoints of communication, not as full-fledged objects. Our case study has not really done this, because we wanted to illustrate the use of certain technologies, and the proper way to partition functionality really depends on the details of your actual application and network latencies.

You can also use the CacheDuration property on a Web method or the Cache property of the HttpContext class to cache information to avoid network overhead.

for RuBoard


Application Development Using C# and .NET
Application Development Using C# and .NET
ISBN: 013093383X
EAN: 2147483647
Year: 2001
Pages: 158

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