XML Web Services and Data

Team-Fly    

 
.NET and COM Interoperability Handbook, The
By Alan Gordon
Table of Contents
Chapter Ten.  XML Web Services

XML Web Services and Data

So far, there is nothing from a technological standpoint in this Web service that isn't like the previous Web service. Therefore, let's add another method to the Web service that will return an amortization table for a loan. An amortization table is a table with one entry for each payment on the loan. Each entry shows the amount of principal and interest in the payment and the remaining balance after the payment. You can return tabular data like this using a Web service in two ways: (1) using an ADO.NET dataset or (2) using a custom class.

Returning Data Using a Custom Class

Let's look first at returning the amortization table using a custom class. Here is a Payment class that you can use to hold each entry in the amortization table:

 1.  namespace FinancialWebService 2.  { 3.      public class Payment 4.      { 5.          public Payment(short mnth,decimal amt, 6.        decimal prinAmt,decimal intrstAmt, 7.        decimal balance) 8.          { 9.             this.Month=mnth; 10.         this.Amount=amt; 11.         this.PrincipleAmount=prinAmt; 12.         this.InterestAmount=intrstAmt; 13.         this.Balance=balance; 14.         } 15.         public Payment() {} 16.         public short Month; 17.         public decimal Amount; 18.         public decimal PrincipleAmount; 19.         public decimal InterestAmount; 20.         public decimal Balance; 21.     } 22. } 

This class has five member variables : a month, a payment amount, a principle amount, an interest amount, and a remaining balance. This is all the information you need for each entry in the amortization table. Here is a web service method that returns an Amortization table for a loan using the Payment class:

 1.  [WebMethod] 2.  public Payment[] AmortizationTable(short numMonths, 3.      double interestRate, decimal loanAmt) 4.  { 5.      short i, numLoops; 6.      double monthlyRate; 7.      decimal monthlyPmt, remainingBalance, 8.        principle, interest; 9.      Payment[] payments; 10.     payments=new Payment[numMonths]; 11.     monthlyRate=interestRate/1200; // Convert A.P.R. 12.                //to decimal monthly rate 13.     monthlyPmt=MonthlyPayment(numMonths, 14.       interestRate,loanAmt); 15.     remainingBalance=loanAmt; 16.     numLoops=(short)(numMonths-1); 17.     for (i=0;i<numLoops;i++) 18.     { 19.       interest=decimal.Round( 20.         (decimal)monthlyRate*remainingBalance,2); 21.       principle=monthlyPmt-interest; 22.       remainingBalance= 23.          remainingBalance-principle; 24.       payments[i]=new Payment((short)(i+1), 25.       monthlyPmt,principle,interest, 26.       remainingBalance); 27.     } 28. // Calculate the final payment so the balance is zero; 29.     if (numMonths > 0) 30.     { 31.       interest=decimal.Round((decimal) 32.         monthlyRate*remainingBalance,2); 33.       principle= 34.         decimal.Round(remainingBalance,2); 35.       monthlyPmt=interest+principle; 36.       remainingBalance=(Decimal)0.0; 37.       payments[numMonths-1]= 38.         new Payment((short)(i+1), 39.              monthlyPmt,principle, 40.              interest,remainingBalance); 41.     } 42.     return payments; 43. } 

I won't go into the details of the math for this method. The key lines for this discussion are lines 9 and 10, where I declare and instantiate an array of payment objects. I then populate the array with payment information for the loan on lines 11 through 41, and I return the array on line 42. I don't have to do anything special to return a complex type like this from a Web service. If you look at the WSDL file for the Web service, you will see that the Payment type appears there.

 <s:complexType name="Payment">   <s:attribute name="Month" type="s:short" />   <s:attribute name="Amount" type="s:decimal" />   <s:attribute name="Principle" type="s:decimal" />   <s:attribute name="Interest" type="s:decimal" />   <s:attribute name="Balance" type="s:decimal" /> </s:complexType> 

If you regenerate the proxy for the Web service, you will also see that the Payment type now appears in the wsdl.exe-generated source code.

 public class Payment {         /// <remarks/>         public short Month;         /// <remarks/>         public System.Decimal Amount;         /// <remarks/>         public System.Decimal PrincipleAmount;         /// <remarks/>         public System.Decimal InterestAmount;         /// <remarks/>         public System.Decimal Balance;     } } 

An important point to mention here is that only the state of the Payment class is carried across to the WSDL file and the generated proxy class. If you added additional methods to the original implementation of the Payment class, those methods will not be reflected in the WSDL file or the proxy. An XML Web service can only transport data, not code. Here is an example of the XML response you will see when you call the Amortization method:

[View full width]
 
[View full width]
<?xml version="1.0" encoding="utf-8"?> <ArrayOfPayment xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/ graphics/ccc.gif 2001/XMLSchema-instance" xmlns="http://tempuri.org/"> <Payment> <Month>1</Month> <Amount>2216.58</Amount> <PrincipleAmount>341.58</PrincipleAmount> <InterestAmount>1875</InterestAmount> <Balance>359658.42</Balance> </Payment> <Payment> <Month>2</Month> <Amount>2216.58</Amount> <PrincipleAmount>343.36</PrincipleAmount> <InterestAmount>1873.22</InterestAmount> <Balance>359315.06</Balance> </Payment> <Payment> <Month>3</Month> <Amount>2216.58</Amount> <PrincipleAmount>345.15</PrincipleAmount> <InterestAmount>1871.43</InterestAmount> <Balance>358969.91</Balance> </Payment> ... </ArrayOfPayment>

Notice that the ASP.NET Web services infrastructure serialized the array of payment objects into an XML representation with an ArrayOf[ClassName] top-level element for the array and then one Payment subelement for each element of the array. Each member variable of the Payment class is a subelement of the Payment element. If you don't like the default XML representation that the ASP.NET runtime uses for the Payment class, you can change it. For instance, if I wanted to change the Payment class so that the member variables of the class appeared as attributes of the Payment element instead of subelements, I would only need to change the definition of the Payment class to the following:

 1.  namespace FinancialWebService 2.  { 3.      using System.Xml.Serialization; 4.      [XmlRoot("Payment")] 5.      public class Payment 6.      { 7.        public Payment(short mnth,decimal amt, 8.          decimal prinAmt,decimal intrstAmt, 9.          decimal balance) 10.       { 11.         this.Month=mnth; 12.         this.Amount=amt; 13.         this.PrincipleAmount=prinAmt; 14.         this.InterestAmount=intrstAmt; 15.         this.Balance=balance; 16.       } 17.       public Payment() {} 18. 19.       [XmlAttribute("Month")] 20.       public short Month; 21.       [XmlAttribute("Amount")] 22.       public decimal Amount; 23.       [XmlAttribute("Principle")] 24.       public decimal PrincipleAmount; 25.       [XmlAttribute("Interest")] 26.       public decimal InterestAmount; 27.       [XmlAttribute("Balance")] 28.       public decimal Balance; 29.     } 30. } 

Using the XmlRoot, XmlAttribute, and XmlElement attributes, which can be found in the System.Xml.Serialization namespace, you can control how instances of the class are rendered as XML. In this case, I have specified that the member variables of the Payment class should be attributes of a root element called Payment. If I call the AmortizationTable method again, you can see that the generated XML will now look as follows :

[View full width]
 
[View full width]
<?xml version="1.0" encoding="utf-8"?> <ArrayOfPayment xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/ graphics/ccc.gif 2001/XMLSchema-instance" xmlns="http://tempuri.org/"> <Payment Month="1" Amount="469.7" Principle="369.7" Interest="100" Balance="19630.3" /> <Payment Month="2" Amount="469.7" Principle="371.55" Interest="98.15" Balance="19258.75" /> <Payment Month="3" Amount="469.7" Principle="373.41" Interest="96.29" Balance="18885.34" /> <Payment Month="4" Amount="469.7" Principle="375.27" Interest="94.43" Balance="18510.07" /> </ArrayOfPayment>

Notice that the member variables of the Payment class appear as attributes of the Payment, XML element.


Team-Fly    
Top
 


. Net and COM Interoperability Handbook
The .NET and COM Interoperability Handbook (Integrated .Net)
ISBN: 013046130X
EAN: 2147483647
Year: 2002
Pages: 119
Authors: Alan Gordon

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