Design Guidelines for XML Web Services Created Using ASP.NET

XML Web services is a powerful technology for providing services that can be accessed programmatically across the Internet. The following recommendations will help you create proficient XML Web services:

  • XML Web services support both synchronous and asynchronous communication between the client and the server that hosts the XML Web service. Under synchronous communication, the client sends a request for a service to the service host server and waits for the response. This prevents the client from performing other operations while waiting for the results. Asynchronous communication, however, causes the client to continue processing other tasks as it waits for a response. The client responds to the result of the service request when it becomes available.

    When you use the Web Services Description Language tool (Wsdl.exe) to create your proxy class, it generates the standard, synchronous versions and asynchronous versions of the methods in the class. The asynchronous versions consist of two methods called Begin and End. The Begin method is used to initiate the XML Web service, while the End method retrieves the results.

    Using asynchronous communication improves system usage and avoids delays on the client while it waits for the XML Web service results.

    The following code example demonstrates how to make an asynchronous call to an XML Web service from a client application.

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Net" %>
    <html>
       <script language="C#" runat="server">
          void EnterBtn_Click(Object Src, EventArgs E) 
          {
             MyMath.Math math = new MyMath.Math();
             // Call to Add XML Web service method asynchronously 
             // and then wait for it to complete.
             IAsyncResult result =
                             math.BeginAdd(Convert.ToInt32(Num1.Text),
                                           Convert.ToInt32(Num2.Text),
                                           null,
                                           null);
             // Wait for asynchronous call to complete.
             result.AsyncWaitHandle.WaitOne();
             // Complete the asynchronous call to Add XML Web service method.
             float total = math.EndAdd(result);
             // Display results in a Label control.
             Total.Text = "Total: " + total.ToString();
          }
       </script>
    <body>
       <form action="MathClient.aspx" runat=server>
          <font face="Verdana"> 
             Enter the two numbers you want to add and then press 
             the Total button.
             <p>
             Number 1: 
             <asp:textbox id="Num1" 
             runat=server/>  
             +
             Number 2: 
             <asp:textbox id="Num2" 
                  runat=server/> 
             =
             <asp:button id="Total_Button"
                  text="Total" 
                  OnClick="EnterBtn_Click" 
                  runat=server/>
             <p>
             <asp:label id="Total" runat=server/>
          </font>
        </form>
    </body>
    </html>
    [Visual Basic]
    <%@ Page Language="VB" %>
    <%@ Import Namespace="System.Net" %>
    <html>
       <script language="VB" runat="server">
          Sub EnterBtn_Click(Src As Object, E As EventArgs) 
             Dim math As New MyMath.Math()
             ' Call to Add XML Web service method asynchronously 
             ' and then wait for it to complete.
             Dim result As IAsyncResult = _
                             math.BeginAdd(Convert.ToInt32(Num1.Text), _
                                           Convert.ToInt32(Num2.Text), _
                                           Nothing, _
                                           Nothing)
    
             ' Wait for asynchronous call to complete.
             result.AsyncWaitHandle.WaitOne()
             ' Complete the asynchronous call to Add XML Web service method.
             Dim addtotal As Single = math.EndAdd(result)
             ' Display results in a Label control.
             Total.Text = "Total: " & addtotal.ToString()
          End Sub
       </script>
    <body>
       <form action="MathClient.aspx" runat=server>
          <font face="Verdana"> 
             Enter the two numbers you want to add and then press 
             the Total button.
             <p>
             Number 1: 
             <asp:textbox id="Num1" 
             runat=server/>  
             +
             Number 2: 
             <asp:textbox id="Num2" 
                  runat=server/> 
             =
             <asp:button id="Total_Button"
                  text="Total" 
                  OnClick="EnterBtn_Click" 
                  runat=server/>
             <p>
             <asp:label id="Total" runat=server/>
          </font>
        </form>
    </body>
    </html>
    

    For additional information on asynchronous communication, see Communicating with XML Web Services Asynchronously.

  • Making numerous service requests across the Internet can affect the performance of the client application. When designing your XML Web service, make efficient use of service requests by creating methods that group related information together. For example, suppose you have an XML Web service that retrieves information about a book. Instead of having separate methods to retrieve the book title, author, and publisher, create a method that returns all this information in one service request. It is more efficient to transfer a large block of information at one time than multiple smaller blocks of information.

    The following code example demonstrates how to group related information into a single XML Web service method.

    <%@ WebService Language="C#" Class="DataService" %>
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Web.Services;
    public class DataService {
       [WebMethod]
       public DataSet GetTitleAuthors() {
            SqlConnection myConnection = new SqlConnection("Persist Security Info=False;Integrated Security=SSPI;server=localhost;database=pubs");
            SqlDataAdapter myCommand1 = new SqlDataAdapter ("select * from Authors", myConnection);
            SqlDataAdapter myCommand2 = new SqlDataAdapter("select * from Titles", myConnection);
            DataSet ds = new DataSet();
            myCommand1.Fill(ds, "Authors");
            myCommand2.Fill(ds, "Titles");
            return ds;
       }
    }
    [Visual Basic]
    <%@ WebService Language="VB" Class="DataService" %>
    Imports System
    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.Web.Services
    Public Class DataService   
        <WebMethod> _
        Public Function GetTitleAuthors() As DataSet
            Dim myConnection As New SqlConnection("Persist Security Info=False;Integrated Security=SSPI;server=localhost;database=pubs")
            Dim myCommand1 As New SqlDataAdapter("select * from Authors", myConnection)
            Dim myCommand2 As New SqlDataAdapter("select * from Titles", myConnection)
            Dim ds As New DataSet()
            myCommand1.Fill(ds, "Authors")
            myCommand2.Fill(ds, "Titles")
            Return ds
        End Function
    End Class
    
  • When designing your XML Web service, be sure to use standard object-oriented programming practices. Use encapsulation to hide implementation details. For more complex XML Web services, you can use inheritance and polymorphism to reuse code and simplify your design.

    The following code example demonstrates how to use inheritance to create an XML Web service that performs math calculations.

    <%@ WebService Language="C#" Class="Add" %>
    using System;
    using System.Web.Services;
    abstract public class MathService : WebService 
    {
       [WebMethod]
       abstract public float CalculateTotal(float a, float b);
    }
    public class Add : MathService 
    {
       [WebMethod]
       override public float CalculateTotal(float a, float b)
       {
           return a + b;
       }
    }
    public class Subtract : MathService 
    {
       [WebMethod]
       override public float CalculateTotal(float a, float b)
       {
           return a - b;
       }
    }
    public class Multiply : MathService 
    {
       [WebMethod]
       override public float CalculateTotal(float a, float b)
       {
           return a * b;
       }
    }
    public class Divide : MathService 
    {
       [WebMethod]
       override public float CalculateTotal(float a, float b)
       {
           if (b==0) 
              return -1;
           else
              return a / b;
       }
    }
    [Visual Basic]
    <%@ WebService Language="VB" Class="Add" %>
    Imports System
    Imports System.Web.Services
    MustInherit Public Class MathService : Inherits WebService    
        <WebMethod> _
        Public MustOverride Function CalculateTotal(a As Single, _
                            b As Single) As Single
    End Class
    Public Class Add : Inherits MathService    
        <WebMethod> _
        Public Overrides Function CalculateTotal(a As Single, _
                         b As Single) As Single
            Return a + b
        End Function
    End Class 
    Public Class Subtract : Inherits MathService
        <WebMethod> _
        Public Overrides Function CalculateTotal(a As Single, _
                         b As Single) As Single
            Return a - b
        End Function
    End Class 
    Public Class Multiply : Inherits MathService
        <WebMethod> _
        Public Overrides Function CalculateTotal(a As Single, _
                         b As Single) As Single
            Return a * b
        End Function
    End Class 
    Public Class Divide : Inherits MathService
        <WebMethod> _
        Public Overrides Function CalculateTotal(a As Single, _
                         b As Single) As Single
            If b = 0 Then
                Return - 1
            Else
                Return a / b
            End If
        End Function
    End Class
    
  • Use output caching to improve the performance of your XML Web service. When output caching is turned on, the results of a service request are stored in the output cache for a specified duration. If a similar XML Web service request is made, the result can be obtained from the cache, rather than recalculating it. This improves the reaction time of the XML Web service by reducing the processing required by the XML Web service server. Caching can be performed on both the client and the server. The Duration property allows you to specify the amount of time to cache the output of an XML Web service.

    The directive to enable output caching on the client is:

    <%@ OutputCache Duration="60" %>
    

    The following code example demonstrates how to use the Duration property on the client application to specify output caching for a period of 60 seconds.

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Net" %>
    <%@ OutputCache Duration="60" VaryByParam="none" %>
    <html>
       <script language="C#" runat="server">
          void EnterBtn_Click(Object Src, EventArgs e) 
          {
             MyMath.Math math = new MyMath.Math();
             // Call the XML Web service.
             float total = math.Add(Convert.ToInt32(Num1.Text),
                                  Convert.ToInt32(Num2.Text));
             // Display the results in a Label control.
             Total.Text = "Total: " + total.ToString();
          }
       </script>
    <body>
       <form action="MathClient.aspx" runat=server>
          <font face="Verdana"> 
             Enter the two numbers you want to add and press 
             the Total button.
             <p>
             Number 1: 
             <asp:textbox id="Num1" 
             runat=server/>  
             +
             Number 2: 
             <asp:textbox id="Num2" 
                  runat=server/> 
             =
             <asp:button id="Total_Button"
                  text="Total" 
                  OnClick="EnterBtn_Click" 
                  runat=server/>
             <p>
             <asp:label id="Total" runat=server/>
          </font>
        </form>
    </body>
    </html>
    [Visual Basic]
    <%@ Page Language="VB" %>
    <%@ Import Namespace="System.Net" %>
    <%@ OutputCache Duration="60" VaryByParam="none" %>
    <html>
       <script language="VB" runat="server">
          Sub EnterBtn_Click(Src As Object, e As EventArgs) 
             Dim math As New MyMath.Math()
             ' Call the XML Web service.
             Dim addtotal As Single = math.Add(Convert.ToInt32(Num1.Text), _
                                  Convert.ToInt32(Num2.Text))
             ' Display the results in a Label control.
             Total.Text = "Total: " & addtotal.ToString()
          End Sub
       </script>
    <body>
       <form action="MathClient.aspx" runat=server>
          <font face="Verdana"> 
             Enter the two numbers you want to add and press 
             the Total button.
             <p>
             Number 1: 
             <asp:textbox id="Num1" 
             runat=server/>  
             +
             Number 2: 
             <asp:textbox id="Num2" 
                  runat=server/> 
             =
             <asp:button id="Total_Button"
                  text="Total" 
                  OnClick="EnterBtn_Click" 
                  runat=server/>
             <p>
             <asp:label id="Total" runat=server/>
          </font>
        </form>
    </body>
    </html>
    

    You can also use the CacheDuration property of the WebMethod attribute class to enable caching on the server. The following code example demonstrates how to use the CacheDuration property on XML Web service methods to specify output caching for a period of 60 seconds.

    <%@ WebService Language="C#" Class="MathService" %>
    using System;
    using System.Web.Services;
    public class MathService : WebService {
       [WebMethod(CacheDuration=60)]
       public float Add(float a, float b)
       {
           return a + b;
       }
       [WebMethod(CacheDuration=60)]
       public float Subtract(float a, float b)
       {
           return a - b;
       }
       [WebMethod(CacheDuration=60)]
       public float Multiply(float a, float b)
       {
           return a * b;
       }
       [WebMethod(CacheDuration=60)]
       public float Divide(float a, float b)
       {
           if (b==0) return -1;
           return a / b;
       }
    }  
    [Visual Basic]
    <%@ WebService Language="VB" Class="MathService" %>
    Imports System
    Imports System.Web.Services
    Public Class MathService
        Inherits WebService 
        <WebMethod(CacheDuration := 60)> _
        Public Function Add(a As Single, b As Single) As Single
            Return a + b
        End Function
    
        <WebMethod(CacheDuration := 60)> _
        Public Function Subtract(a As Single, b As Single) As Single
            Return a - b
        End Function
    
        <WebMethod(CacheDuration := 60)> _
        Public Function Multiply(a As Single, b As Single) As Single
            Return a * b
        End Function
    
        <WebMethod(CacheDuration := 60)> _
        Public Function Divide(a As Single, b As Single) As Single
            If b = 0 Then
                Return - 1
            End If
            Return a / b
        End Function
    End Class
    
  • When designing your XML Web service, try to follow the structure of how a schema is formatted.

  • XML Web services use SOAP as the primary transport and serialization protocol. A SOAP message consists of an optional set of headers and the message body. The header section contains information that can be processed by the infrastructure on the Web server. SOAP does not define any headers. The body section contains information processed by an application, such as the parameters or return value for an XML Web service.

    For additional information on using SOAP headers, see Using SOAP Headers.

  • Provide documentation for your XML Web service, such as a static HTML file, that describes the operation of your service and the data structures. Also include examples of how to use the XML Web service. Do not rely on the service description or the service help page as your only documentation.

See Also

Building XML Web Services Using ASP.NET | Communicating with XML Web Services Asynchronously | Using SOAP Headers