共用方式為


作法:將啟用 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 2012。

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

透過啟用 AJAX 的端點公開 WCF 服務的詳細資訊,請參閱如何:使用設定新增 ASP.NET AJAX 端點主題。

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

  1. 開啟 Visual Studio 2012。

  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 公開端點。

    現在您已準備好要轉換這個服務,以使用 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 作業,並設定 ResponseFormat 屬性以傳回 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="http://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].
    }
}

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

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

  • 如果先新增 WCF 服務,則叫用 ASMX Web 服務上的方法會造成 ConvertValue(Object, Type, String) 中的例外狀況,因為在 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 物件中的表示如下列清單所示:

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

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

差異分類 DataContractJsonSerializer ASP.NET AJAX JavaScriptSerializer
將空的緩衝區 (新的 byte[0]) 還原序列化成 Object (或 Uri 或一些其他的類別)。 SerializationException null
Value 的序列化 {} (或 {"__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 值。

另請參閱