共用方式為


HOW TO:將啟用 AJAX 的 ASP.NET Web 服務移轉至 WCF

本主題將概述用來將基本 ASP.NET AJAX 服務移轉至相等之啟用 AJAX 的 Windows Communication Foundation (WCF) 服務的程序。其中將示範如何建立功能相等的 WCF 版本的 ASP.NET AJAX 服務。然後這兩項服務可以並存使用,或是 WCF 服務可以用於取代 ASP.NET AJAX 服務。

將現有的 ASP.NET AJAX 服務移轉至 WCF AJAX 服務可為您提供下列優點:

  • 您可以使用最少的額外組態,將您的 AJAX 服務公開為 SOAP 服務。
  • 您可以從 WCF 功能獲益,例如追蹤等等。

下列程序假設使用的是 Visual Studio 2008。

在程序之後的範例中,會提供來自本主題中所述程序的程式碼。

如需 透過已啟用 AJAX 端點公開 WCF 服務的詳細資訊,請參閱 HOW TO:使用組態新增 ASP.NET AJAX 端點主題。

若要建立並測試 ASP.NET Web 服務應用程式

  1. 開啟 Visual Studio 2008。

  2. 在 [檔案] 功能表上,選取 [新增]、[專案]、[Web],然後選取 [ASP.NET Web Service 應用程式]。

  3. 將專案命名為 ASPHello,然後按一下 [確定]。

  4. 在 Service1.asmx.cs 檔案中,取消包含 System.Web.Script.Services.ScriptService] 的字行註解以便為此服務啟用 AJAX。

  5. 從 [建置] 功能表中,選取 [建置方案]。

  6. 從 [偵錯] 功能表中,選取 [啟動但不偵錯]。

  7. 在產生的網頁中,選取 HelloWorld 作業。

  8. HelloWorld 測試頁上按一下 [叫用] 按鈕。您應該會收到下列 XML 回應。

    <?xml version="1.0" encoding="utf-8" ?>
    <string xmlns="http://tempuri.org/">Hello World</string>
    
  9. 這個回應會確認您現在有正在運作的 ASP.NET AJAX 服務,而且特別的是,服務現在已在回應 HTTP POST 要求並傳回 XML 的 Service1.asmx/HelloWorld 公開端點。

    如需 如何存取這個服務的詳細資訊,請參閱Using Web Services in ASP.NET AJAX

    現在您已準備好要轉換這個服務,以使用 WCF AJAX 服務了。

建立相等的 WCF AJAX 服務應用程式

  1. 以滑鼠右鍵按一下 [ASPHello] 專案並選取 [新增]、[新增項目],然後選取 [已啟用 AJAX 的 WCF 服務]。

  2. 將服務命名為 WCFHello,然後按一下 [新增]。

  3. 開啟 WCFHello.svc.cs 檔案。

  4. 請從 Service1.asmx.cs 複製 HelloWorld 作業的下列實作。

    public string HelloWorld()
    {
         return "Hello World";
    }
    
  5. 將複製的 HelloWorld 作業的實作貼上至 WCFHello.svc.cs 檔案,以取代下列程式碼。

    public void DoWork()
    {
          // Add your operation implementation here
          return;
    }
    
  6. ServiceContractAttributeNamespace 屬性指定為 WCFHello

    [ServiceContract(Namespace="WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    public class WCFHello
    { … }
    
  7. WebInvokeAttribute 新增至 HelloWorld 作業,並設定 RequestFormat 屬性以傳回 Xml。請注意,如果沒有設定,預設傳回型別為 Json

            [OperationContract]
            [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
            public string HelloWorld()
            {
                return "Hello World";
            }
    
  8. 從 [建置] 功能表中,選取 [建置方案]。

  9. 開啟 WCFHello.svc 檔案,然後從 [偵錯] 功能表中,選取 [啟動但不偵錯]。

  10. 服務現在會在回應 HTTP POST 要求的 WCFHello.svc/HelloWorld 公開端點。HTTP POST 要求無法從瀏覽器來測試,但是端點會傳回下列 XML。

    <string xmlns="https://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
    
  11. WCFHello.svc/HelloWorldService1.aspx/HelloWorld 端點現在的功能是相等的。

範例

下列範例中會提供來自本主題中所述程序的程式碼。

//This is the ASP.NET code in the Service1.asmx.cs file.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Web.Script.Services;

namespace ASPHello
{
    /// <summary>
    /// Summary description for Service1.
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
} 

//This is the WCF code in the WCFHello.svc.cs file.
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace ASPHello
{
    [ServiceContract(Namespace = "WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class WCFHello
    {
        // Add [WebInvoke] attribute to use HTTP GET.
        [OperationContract]
        [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
        public string HelloWorld()
        {
            return "Hello World";
        }

        // Add more operations here and mark them with [OperationContract].
    }
}

DataContractJsonSerializer 不支援 XmlDocument 型別,因為它無法由 XmlSerializer 來序列化。您可以使用 XDocument 型別,或是改為序列化 DocumentElement

如果 ASMX Web 服務正並存升級及移轉至 WCF 服務,請避免將兩種型別對應至用戶端上相同的名稱。如果在 WebMethodAttributeServiceContractAttribute 中使用相同的型別,會造成序列化程式中的例外狀況:

  • 如果先新增 WCF 服務,則叫用 ASMX Web 服務上的方法會造成 ConvertValue 中的例外狀況,因為在 Proxy 中順序的 WCF 樣式定義會取得優先權。
  • 如果先新增 ASMX Web 服務,則叫用 WCF 服務上的方法會造成 DataContractJsonSerializer 中的例外狀況,因為在 Proxy 中順序的 Web 服務樣式定義會取得優先權。

DataContractJsonSerializer 和 ASP.NET AJAX JavascriptSerializer 之間在行為上有許多不同之處。例如,DataContractJsonSerializer 會將字典表示為索引鍵/值配對的陣列,而 ASP.NET AJAX JavascriptSerializer 會將字典表示為實際的 JSON 物件。因此下面是在 ASP.NET AJAX 中表示的字典。

Dictionary<string, int> d = new Dictionary<string, int>();
d.Add(“one”, 1);
d.Add(“two”, 2);

這個字典在 JSON 物件中的表示如下列清單所示:

  • [{"Key":"one","Value":1},{"Key":"two","Value":2}],透過 DataContractJsonSerializer
  • {“one”:1,”two”:2},透過 ASP.NET AJAX JavascriptSerializer

DataContractJsonSerializer 的功能較為強大,因為它可以處理其中金鑰類型不是字串的字典,但是 JavascriptSerializer 卻無法這麼做。然而後者較容易用來處理 JSON。

下表將摘要說明序列化程式之間的許多差異。

差異分類 DataContractJsonSerializer ASP.NET AJAX JavaScriptSerializer

將空的緩衝區 (新的 byte[0]) 還原序列化成 Object (或 Uri 或一些其他的類別)。

SerializationException

null

Value 的序列化

{} (or {"__type":"#System"})

Null

[Serializable] 型別的私用成員序列化

已序列化

未序列化

ISerializable 型別的公用屬性序列化。

未序列化

已序列化

JSON 的 "Extensions"

遵守 JSON 規格,需要在物件成員名稱上加上引號 ({"a":"hello"})。

支援不加引號的物件成員名稱 ({a:"hello"})。

DateTime 以 Coordinated Universal Time (UTC) 時間計算

不支援格式 "\/Date(123456789U)\/" 或 "\/Date\(\d+(U|(\+\-[\d{4}]))?\)\\/)"。

支援格式 "\/Date(123456789U)\/" 和 "\/Date\(\d+(U|(\+\-[\d{4}]))?\)\\/)" 做為 DateTime 值。

字典表示法

KeyValuePair<K,V> 陣列,可處理非字串的金鑰型別。

做為實際的 JSON 物件 - 但只能處理屬於字串的金鑰型別。

逸出字元

一律使用逸出正斜線 (/);絕不允許使用未逸出的無效 JSON 字元,例如 "\n"。

使用逸出斜線 (/) 做為 DateTime 值。

請參閱

工作

HOW TO:使用組態新增 ASP.NET AJAX 端點