為使用 ASP.NET 建立的 XML Web Service 設計方針
XML Web Service 功能強大,所提供的服務可透過網際網路以程式設計方式存取。下列建議可幫助您建立專家級的 XML Web Service:
XML Web Service 可在用戶端及裝載 XML Web Service 的伺服器之間進行同步 (Synchronous) 和非同步 (Asynchronous) 通訊。進行同步通訊時,用戶端會將需要服務的要求傳遞給服務裝載伺服器,並等待回應。如此可避免用戶端在等待結果前執行其他作業。但是,非同步通訊可讓用戶端在等待回應時繼續處理其他作業。用戶端工作完畢後,即回應伺服器要求的結果。
當您使用 Web 服務描述語言工具 (Wsdl.exe) 建立 Proxy 類別時,他會產生類別中方法的標準同步與非同步版本。同步版本包含 Begin 和 End 兩個方法。Begin 方法是用來啟始 XML Web Service,而 End 方法則用於擷取結果。
使用非同步通訊能改善系統使用情況,並避免用戶端等待 XML Web Service 結果時發生延遲。
下列程式碼範例示範如何從用戶端應用程式非同步呼叫 XML Web Service。
<%@ 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>
如需非同步通訊的詳細資訊,請參閱與 XML Web Service 進行非同步通訊。
在網際網路上傳遞數個服務要求可能會影響用戶端應用程式的效能。所以,設計 XML Web Service 時,請將相關資訊集中建立在方法中來有效利用服務要求。例如,假設您的 XML Web Service 擷取書籍資訊,與其用個別方法擷取書名、作者和發行者,不如建立方法將這些資訊放在一個服務要求中傳回。因為一次傳回大區塊資料比起多次傳送小區塊資訊,更有效率。
下列程式碼範例示範如何將相關資訊整合在單一 XML Web Service 方法內。
<%@ 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
設計 XML Web Service 時,請務必使用標準的物件導向程式設計實施方針,使用封裝 (Encapsulation) 來隱藏實作詳細資訊。設計較複雜的 XML Web Service 時,您可以使用繼承 (Inheritance) 和多型 (Polymorphism) 來重複使用程式碼,簡化設計。
下列程式碼範例示範如何使用繼承,建立可執行數學運算的 XML Web Service。
<%@ 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
使用輸出快取改善 XML Web Service 的效能。輸出快取啟動後,服務要求的結果會在輸出快取中儲存一段指定時間。如果出現類似的 XML Web Service 要求,可從快取獲得結果,不需要重新計算結果。如此能減輕 XML Web Service 伺服器所需處理的工作,縮短 XML Web Service 的回應時間。快取可在用戶端和伺服器執行,您也可以使用 Duration 屬性指定快取 XML Web Service 輸出的時間長度。
啟用用戶端輸出快取的指示詞為:
<%@ OutputCache Duration="60" %>
下列程式碼範例示範如何在用戶端應用程式使用 Duration 屬性,指定 60 秒的輸出快取週期 。
<%@ 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>
您也可以使用 WebMethod 屬性類別的CacheDuration 屬性,啟用伺服器上的快取。下列程式碼範例示範如何在 XML Web Service 方法使用 CacheDuration 屬性,指定 60 秒的輸出快取週期 。
<%@ 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
設計 XML Web Service 時,請嘗試按照結構描述格式化的結構進行設計。
XML Web Service 使用 SOAP 為主要傳輸和序列化 (Serialization) 通訊協定。SOAP 訊息是由選擇性的標頭組和訊息主體所組成。標頭的部分包含的資訊可由 Web 伺服器上的基礎架構處理,SOAP 不需要定義任何標頭。至於主體部分包含的資訊,例如 XML Web Service 的參數或傳回值,則由應用程式處理。
如需使用 SOAP 標頭的詳細資訊,請參閱使用 Soap 標頭。
提供 XML Web Service 的文件如靜態 HTML 檔案,說明您的服務和資料結構如何作業,並包含範例說明如何使用 XML Web Service。請勿將服務描述或服務說明網頁當成唯一的文件。
請參閱
使用 ASP.NET 建置 XML Web Service | 與 XML Web Service 進行非同步通訊 | 使用 SOAP 標頭