.NET Web 服務

利用 ServiceStack 建置跨平台 Web 服務

顏樂

下載代碼示例

工作與 Windows 通信基礎 (WCF),因為有優秀支援Visual Studio中框架一樣 我發現它相當容易生成 WCF Web 服務從零開始,並會把它和我的開發環境中運行,無需安裝額外的工具和可轉散發元件。 我將討論跨平臺開發,在這裡,我的經歷所以你可能對此文章感興趣,如果符合下列條件:

  • 你已經熟悉 WCF 和 C#。
  • 你需要建立一個跨平臺的 Web 服務。

我認為我們都同意編寫跨平臺應用程式是在造成最少不便,但有時不可避免。 如果你像我一樣東西 — — Windows 綁定和大量投資在 C# 中 — — 放在一起的跨平臺的 Web 服務可能會引起很大的開銷。 這包括重新配置您心愛的 Windows 計算環境,以適應一種完全不同的開發工具集和可能學習另一種程式設計語言。 在本文中,我將展示如何利用 WCF ServiceStack (開放原始碼.NET 和單聲道其餘 Web 服務框架) 來完成這一任務,無需離開Visual Studio或 Microsoft.NET 框架環境的形像。

有關 Web 服務

一個典型的 Web 服務在描繪出奠定了圖 1

A Typical Web Service Layout
圖 1 典型的 Web 服務佈局

服務層是您定義您的 Web 服務介面的地方。 這是,用戶端需要消耗您的 Web 服務進行交互的唯一層。

業務層通常是重與業務邏輯,很明顯。 這是駐留的 Web 服務實現的肉,保持你的服務層光和合同用戶端/伺服器和通信為重點。

資料層是為了封裝資料訪問和操縱在業務層提供抽象的資料模型。

在本文中,我將重點在服務層。

遠端程序呼叫與資料傳輸物件

某些 Web 服務採取的遠端程序呼叫 (RPC) 的方法,每個請求旨在類似于函式呼叫:

public interface IService {
  string DoSomething(int input);
}

RPC 方法往往使 Web 服務更容易打破介面的更改。 例如,在前面的程式碼片段,如果更高版本的 Web 服務的要求從用戶端來執行 DoSomething 方法的兩個輸入 — — 或需要返回字串值之外的另一個欄位 — — 給老客戶重大更改是不可避免的。 當然,您始終可以創建平行的 DoSomething_v2 方法,要帶兩個輸入的參數,但久而久之會搞亂您的 Web 服務介面和混淆你的消費者,舊的和新的風險。

傳統智慧偏愛面向資料傳輸物件 (DTO) 模型的定義 Web 服務介面。 下面的代碼演示如何在 DTO 模式下可以變成 Web 方法做些什麼:

public class DoSomethingRequest {
  public int Input { get; set; }
}
public class DoSomethingResponse {
  public string Result { get; set; }
}
public interface IService {
  DoSomethingResponse DoSomething(DoSomethingRequest request);
}

繼此學派,每個 Web 方法採用單個 DTO 請求並返回單個 DTO 回應。 想法是添加新的域 DTO 的請求和回應 DTO 不會打破舊的用戶端。

值得注意 RPC 樣式和 DTO 樣式的 Web 服務介面 WCF 支援的但 ServiceStack 僅支援的 DTO 樣式。 ServiceStack 擁抱的遠端 Web 服務介面,較少比較煩瑣,所以和 Web 服務介面設計中的更多 chunkiness 的 DTO 樣式的原則。 這是 ServiceStack,瞭解的關鍵,因為該框架旨在強化原則的方式。

ServiceStack 是什麼?

如前所述,ServiceStack 是一個開源的跨平臺的單聲道 Web 服務框架,和它越來越普及。 用 ServiceStack 生成的 web 服務可以運行在 Windows 環境中,.NET 代碼或單聲道的支援 Linux 環境中。 由單聲道支援的作業系統包括:

  • Linux
  • Mac OS X iOS
  • Sun Solaris
  • BSD
  • Microsoft Windows
  • 任天堂 wii 遊戲機
  • 索尼 PlayStation 3

有關單聲道所支援的平臺的詳細資訊,請參閱單聲道-project.com/Supported_Platforms

如果您喜歡使用的.NET 框架和 WCF,需要部署.NET Web 服務不是 Windows 環境中的,ServiceStack 將是一個理想的選擇。 由於 ServiceStack 和 WCF 的相似性,過渡到另一個需要在開發環境和工具的小調整。 你要繼續寫Visual Studio裡面的 C# 代碼。

ServiceStack 強制遠端 Web 服務最佳實踐、 基於公約 DTO 標準為其 Web 服務介面,而 WCF 留給您自由定義 Web 服務 API,你看看合適。 ServiceStack 還提供預置的回應狀態物件,可用於撰寫 DTO,鼓勵更加直接和簡單的錯誤處理方案的反應。 可以輕鬆地實現這與 WCF,雖然它不是明顯的路線。 最新版本的 ServiceStack 也提供了類似于基於異常的錯誤處理機制 — — 雖然不是偏愛­ticated 作為 — — WCF 基於過失的錯誤處理通過故障的合同。

由 ServiceStack 強制執行的標準容易實現在 WCF 與一個小的額外打字。 然而,除了便攜性,ServiceStack 是一個可行的辦法,建立一個 rest 風格的 Web 服務,因為它建立了簡化路由的 HTTP URI 的公約。 同時,ServiceStack 部隊每個 Web 服務請求,將在一個單獨的類,促進自然分離關注 rest 風格的服務模型。

ServiceStack 還提供了其他好處,預置的伐木和基本資料驗證實用程式。 你可以閱讀更多關於在 servicestack ServiceStack。 淨。

本文假定您有一些熟悉 WCF 和.NET 框架。 為了更好地展示 WCF 概念可以如何轉化為 ServiceStack 的概念,我首先會在 WCF 中實現服務層。 我會告訴你如何通過將它移植到等效的 Web 服務使用 ServiceStack 轉變為跨平臺的 Web 服務的 WCF Web 服務。

構建一個簡單的 WCF Web 服務

為了演示如何 ServiceStack 可以作為替代 WCF 在多平臺環境中,我會用一個簡單的 WCF Web 服務啟動。

Web 服務是瑣細的餐廳的票務系統,稱為 TicketService,實現以下服務合同:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue();
  [OperationContract]
  void QueueTicket(Ticket ticket);
  [OperationContract]
  Ticket PullTicket();
}

TicketService 允許其用戶端佇列新票證、 拉出一張票從佇列和檢索當前佇列中的所有門票的完整清單。

Web 服務三個Visual Studio專案,如圖所示,在圖 2(運行我的樣品溶液,可在下載 archive.msdn.microsoft.com/mag201308Services,需要Visual Studio2012年與 Web 開發人員工具和.NET 框架 4.5)。

WCF Ticket Service Visual Studio Projects
圖 2 WCF 票務服務Visual Studio專案

這三個專案簡要說明如下:

  • TicketSystem.ServiceContract 專案是服務介面定義的位置。
  • TicketSystem.TicketProcessor 專案包含 Web 服務的業務邏輯的實現細節。 此專案不包含引用 wcf。
  • WcfServer 專案實現票務­System.ServiceContracts 和 Web 主機在 IIS 中的服務。

我還把 WCF 用戶端使用 TicketService。 WCF 用戶端是一個主控台應用程式使用從將 WCF 服務引用添加到 TicketService 生成的代碼與在 IIS 中使用 SOAP 的 Web 服務進行通信。 下面是用戶端主控台執行:

static void Main(string[] args) {
  Console.Title = "WCF Console Client";
  using (TicketServiceClient client = new TicketServiceClient()) {
    Ticket[] queuedTickets = client.GetAllTicketsInQueue();
    foreach (Ticket ticket in queuedTickets) {
      PrintTicket(ticket);
    }
  }
}

中所示的資訊服務的用戶端代碼執行圖 3

The WCF Console Client
圖 3 主控台 WCF 用戶端

建立等效 ServiceStack Web 服務

先決條件與 ServiceStackServiceStack 與工作,首先必須下載可轉散發元件。 若要執行此操作最簡單的方法是通過 NuGetVisual Studio拓­sion 使您可以輕鬆地安裝和更新協力廠商庫和工具。 你可以下載並安裝用戶端從 NuGet nuget.codeplex.com。 NuGet 安裝後,您應該看到Visual Studio中的功能表項目所示圖 4

The NuGet Package Manager Console in Visual Studio
圖 4Visual Studio中,NuGet封裝管理員主控台

現在我會做分步攻略關於如何創建一個 ServiceStack Web 服務,相當於我先前建立的 WCF Web 服務。

首先,採取的 WCF Web 服務示例作為起始點。 然後從解決方案中刪除 WcfClient 和 WcfServer 專案。 這些專案是特定于 WCF,和以後他們就會替換與 ServiceStack 相容的專案。

在封裝管理員主控台視窗中,選擇 TicketSystem.ServiceContract 的專案。 在命令提示符下,鍵入"安裝包 ServiceStack,"如圖所示,在圖 5

Installing ServiceStack Redistributables with NuGet Package Manager
圖 5 安裝可轉散發元件 ServiceStack NuGet封裝管理員

這一步下載最新的可轉散發元件有必要建立一個使用 ServiceStack 的.NET Web 服務。 可轉散發元件正在上演"套裝軟體"放置在您的Visual Studio解決方案根資料夾的資料夾名稱下。 另外,DLL 的引用添加到 TicketSystem.ServiceContract 專案。 是在您的專案根資料夾中創建一個 packages.config 檔為您提供每個 ServiceStack dll 的版本和運行時資訊:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="ServiceStack" version="3.9.46" 
    targetFramework="net45" />
  <package id="ServiceStack.Common” version=“3.9.46”
    targetFramework="net45" />
  <package id="ServiceStack.OrmLite.SqlServer" version="3.9.45"
    targetFramework="net45" />
  <package id="ServiceStack.Redis" version="3.9.45"
    targetFramework="net45" />
  <package id="ServiceStack.Text" version="3.9.46"
    targetFramework="net45" />
</packages>

下一步,將轉換到 ServiceStack 可以理解的東西 TicketSystem.ServiceContract 專案中定義的 WCF 資料合同。

WCF 資料合同轉換資料合同 ServiceStack WCF 使用資料合同建立的用戶端和伺服器之間的通信手段。 ServiceStack 相同。 WCF 需要適當的屬性都放任何資料物件和資料成員,您想要序列化和送絲 ; 否則,WCF 簡單地忽略它們。 這是 ServiceStack 和 WCF 與的不同。 ServiceStack 將所有平原舊 CLR 物件序列 (思卡爾) 的服務合同中引用和使其可見到用戶端。 下面是 WCF 和 TicketService 介面在同一票資料合同參考 ServiceStack 代碼表示。

這裡是 WCF <Ticket> 合同的資料:

[DataContract]
public class Ticket {
  [DataMember]
  public int TicketId { get; set; }
  [DataMember]
  public int TableNumber { get; set; }
  [DataMember]
  public int ServerId { get; set; }
  [DataMember]
  public List<Order> Orders { get; set; }
  [DataMember]
  public DateTime Timestamp { get; set; }
}

這裡是 ServiceStack <Ticket> 合同的資料:

public class Ticket {
  public int TicketId { get; set; }
  public int TableNumber { get; set; }
  public int ServerId { get; set; }
  public List<Order> Orders { get; set; }
  public DateTime Timestamp { get; set; }
}

服務的主要區別­堆疊和 WCF 服務介面就是 ServiceStack 放的服務介面的附加限制。 ServiceStack 規定每個唯一的請求是物件所標識唯一的請求,因為沒有任何概念的 Web 服務"操作"(即,方法名稱) 在世界中的 ServiceStack。 這意味著你不能重用 DTO 跨多個服務實現與 ServiceStack 的請求。 ServiceStack Web 服務操作的所有合同將都等同于類似于以下的 WCF 服務合同:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue(GetAllTicketsInQueueRequest request);
  [OperationContract]
  void QueueTicket(QueueTicketRequest request);
  [OperationContract]
  Ticket PullTicket(PullTicketRequest request);
}

前面的代碼是什麼比原始的 RPC 樣式 TicketService WCF 服務介面所示,但轉換以擁抱 DTO 公約:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue();
  [OperationContract]
  void QueueTicket(Ticket ticket);
  [OperationContract]
  Ticket PullTicket();
}

這裡是等效的 TicketService ServiceStack 服務介面:

public class GetAllTicketsInQueueRequest {}
public class QueueTicketRequest {
  public Ticket Ticket { get; set; }
}
public class PullTicketRequest {}
public interface ITicketService {
  List<Ticket> Any(GetAllTicketsInQueueRequest request);
  void Any(QueueTicketRequest request);
  Ticket Any(PullTicketRequest request);
}

ServiceStack 支援不同的操作,如有 Get 和 Post。 您的選擇在這裡僅影響的 HTTP 要求。 指定任何 Web 服務請求是指可以通過 HTTP GET 和 HTTP POST 叫用作業。 這種強制措施,簡化了 rest 風格的 Web 服務實現,這已經超出了本文的範圍。 要將您的 ServiceStack Web 服務變成 rest 風格的 Web 服務,只需添加 URL [Route(...)]向您的 Web 服務請求聲明屬性。

創建ASP.NET託管 ServiceStack Web 服務現在,你有 ServiceStack Web 服務定義的 Web 服務介面,它是執行它,把它推出的時間。

首先,添加ASP.NET空 Web 應用程式。 這是線在選擇以主機為方便我 ServiceStack Web 服務的方式。 它不是唯一的宿主 Web 服務建立在 ServiceStack 基礎上的方法。 你還可以承載內部 Windows 服務或在運行下一個 Web 服務器,或甚至獨立的一個主控台應用程式的表單中的服務。

此Visual Studio專案 ServiceStackServer 的名字 它是相當於 WCF 服務的代碼示例中的 WcfServer 專案。

使用 NuGet封裝管理員主控台將 ServiceStack 引用添加到 ServiceStackServer 中所示圖 6

Add ServiceStack Library References to the ServiceStackServer Project
圖 6 ServiceStack 庫專案增加參考 ServiceStackServer

現在你有你的需要來實現 ITicketService 介面。 TicketService 類必須擴展 ServiceStack.Service­Interface.Service 類提供的框架下,像這樣:

public class TicketService : ServiceStack.ServiceInterface.Service,
  ITicketService {
  public List<Ticket> Any(GetAllTicketsInQueueRequest request) {
    // Implement ...
}
  public void Any(QueueTicketRequest request) {
    // Implement ...
}
  public Ticket Any(PullTicketRequest request) {
    // Implement ...
}
}

一切都是 WCF 執行相同。

接下來,添加全域應用程式類命名 Global.asax 到 ServiceStackServer 專案,如中所示圖 7。 這是您在初始化ASP.NETWeb 應用程式。

Add Global.asax to ServiceStackServer
圖 7 添加 Global.asax ServiceStackServer

你需要從 ServiceStack.WebHost.End 繼承­點。如果你想要承載您的 Web 服務ASP.NET應用程式內的 AppHostBase 類。 請參閱圖 8 的範例。

圖 8 承載ASP.NET裡面 ServiceStack Web 服務

public class Global : System.Web.HttpApplication {
  public class TicketServiceHost : 
    ServiceStack.WebHost.Endpoints.AppHostBase {
    // Register your Web service with ServiceStack.
public TicketServiceHost()
      : base("Ticket Service", typeof(TicketService).Assembly) {}
    public override void Configure(Funq.Container container) {
      // Register any dependencies your services use here.
}
  }
  protected void Application_Start(object sender, EventArgs e) {
    // Initialize your Web service on startup.
new TicketServiceHost().Init();
  }
}

如果在運行 IIS 7 下及更高版本,配置項中展出圖 9 必須添加到 Web.config 檔。

圖 9 Web.config File 的 IIS 7 和更高版本

<configuration>
  <system.web>...</system.web>
  <!--Required for IIS 7 (and above) -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <add path="*" name="ServiceStack.Factory"
        type="ServiceStack.WebHost.Endpoints.
ServiceStackHttpHandlerFactory, ServiceStack"
        verb="*" preCondition="integratedMode"
          resourceType="Unspecified"
        allowPathInfo="true" />
    </handlers>
  </system.webServer>
</configuration>

ServiceStack Web 應用程式啟動時,您的服務合同列出作為中繼資料操作,如圖所示,在圖 10。 現在您的 Web 服務是準備接受用戶端請求。 在下一節中,我將提供一些消費者例子 ServiceStack Web 服務。


圖 10 TicketService 中繼資料

ServiceStack 內置的用戶端

發展集團是非常坦率的反對 ServiceStack 生成 Web 服務用戶端代碼,所以框架提供了一套服務下所列的內置 Web 服務用戶端的­Stack.ServiceClient.Web 命名空間。 所有內置的用戶端執行 ServiceStack.Service.IServiceClient。 那些支援其餘執行 ServiceStack.Service.IRestClient。

可用的客戶包括:

  • JsonServiceClient
  • JsvServiceClient
  • XmlServiceClient
  • MsgPackServiceClient
  • ProtoBufServiceClient
  • Soap11ServiceClient
  • Soap12ServiceClient

每個支援一種不同的序列化/反序列化格式。 它們的用法是可以互換的因為他們實施了一套通用的介面。

為了簡單起見,創建主控台應用程式中調用 ServiceStackClient 來消耗你的 ServiceStack 票­使用 JsvServiceClient 的服務。 如果你想要嘗試一下不同的用戶端,只需替換以前列出的可用客戶任何的端 JsvServiceClient 以下代碼:

static void Main(string[] args) {
  Console.Title = "ServiceStack Console Client";
  using (var client = new JsvServiceClient("http://localhost:30542")) {
    List<Ticket> queuedTickets =
      client.Send<List<Ticket>>(new GetAllTicketsInQueueRequest());
    if (queuedTickets != null) {
      foreach (Ticket ticket in queuedTickets) {
        PrintTicket(ticket);
      }
    }
  }
}

主控台應用程式中執行以下操作:

  • 查詢 TicketService 佇列中的所有車票。
  • 列印出它從 TicketService 回來的結果票。

在主控台輸出是完全相同作為生成 WCF 用戶端上,所示的圖 3

更多優惠

這篇文章只皮毛上 ServiceStack 已提供 WCF 使用者尋求跨平臺解決方案。 我甚至還沒有討論進行流式處理,非同步請求和訊息佇列,例如 ServiceStack 的支援。

正如你所看到的幾個額外的步驟生成所需 ServiceStack Web 服務,而不是一個 WCF Web 服務。 不過,這種努力是相當微不足道,變換成一個多平臺的 ServiceStack Web 服務的 Windows 綁定 WCF Web 服務的服務層。 如果去不同的路線,尋找平臺的獨立性 — — 例如,使用JAVAWeb 服務 — — 的努力和學習曲線會一直大得多的比較。

綜合考慮,如果您的 Web 服務註定的只能在 Windows 作業系統上運行,然後 WCF 是可以說的更好的解決方案。 有較少的系統開銷構建 WCF Web 服務在 Windows 環境中,從零開始時和你沒有另一個協力廠商發行,維護和部署到目標系統。

顏 Le 是高級軟體工程師密切合作,與 WCF 最近開始為 Web 服務的跨平臺解決方案探索 ServiceStack.

感謝以下技術專家對本文的審閱:安德魯 Oakley (Microsoft)
安德魯 Oakley 是高級專案經理模式 & 團隊的做法。 之前成為專案經理,安德魯Visual Studio和.NET 平臺花了兩年來,作為技術的福音傳教士。 他當前專案的重點是圍繞建設不羈的持久性系統使用關係和 NoSQL 資料存儲的資料訪問指導。