共用方式為


自我託管 ASP.NET Web API 1 (C#)

作者:Mike Wasson

本教學課程旨在示範如何在主控台應用程式內託管 Web API。 ASP.NET Web API 不需要 IIS。 您可以在自己的主機處理序中自我託管 Web API。

新的應用程式應該使用 OWIN 來自我託管 Web API。 請參閱使用 OWIN 自我託管 ASP.NET Web API 2

教學課程中使用的軟體版本

  • Web API 1
  • Visual Studio 2012

建立主控台應用程式專案

啟動 Visual Studio,然後從 [開始] 頁面中選取 [新增專案]。 或者,從 [檔案] 功能表中選取 [新增],然後選取 [專案]

在 [範本] 窗格中,選取 [已安裝的範本],然後展開 [Visual C#] 節點。 在 [Visual C#] 底下,選取 [Windows]。 在專案範本清單中,選取 [主控台應用程式]。 將專案命名為「SelfHost」,然後按一下 [確定]

[新增專案] 對話方塊的螢幕擷取畫面,其中顯示資料夾清單中的 Visual C# 項目,以及以灰色醒目提示的 Windows Forms 應用程式項目。

設定目標架構 (Visual Studio 2010)

如果您使用 Visual Studio 2010,請將目標架構變更為 .NET Framework 4.0。 (根據預設,專案範本是以 .Net Framework 用戶端設定檔為目標。)

在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [屬性]。 在 [目標架構] 下拉式清單中,將目標架構變更為 .NET Framework 4.0。 當系統提示您套用變更時,按一下 [是]

[方案總管] 視窗的螢幕擷取畫面,其中顯示 [目標架構] 下拉式清單,並以藍色醒目提示 .NET Framework 4 項目。

安裝 NuGet 套件管理員

NuGet 套件管理員是將 Web API 組件新增至非 ASP.NET 專案最簡單的方式。

若要檢查是否已安裝 NuGet 套件管理員,請按一下 Visual Studio 中的 [工具] 功能表。 如果您看到名為 NuGet 套件管理員的功能表項目,則表示您有 NuGet 套件管理員。

若要安裝 NuGet 套件管理員:

  1. 啟動 Visual Studio。
  2. 從 [工具] 功能表上,選取 [擴充功能和更新]
  3. 在 [擴充功能和更新] 對話方塊中,選取 [線上]
  4. 如果您沒有看到「NuGet 套件管理員」,請在搜尋方塊中輸入「nuget 套件管理員」。
  5. 選取 [NuGet 套件管理員],然後按一下 [下載]
  6. 下載完成之後,系統會提示您進行安裝。
  7. 安裝完成之後,系統可能會提示您重新啟動 Visual Studio。

[擴充功能和更新] 對話方塊的螢幕擷取畫面,其中顯示搜尋結果中的 NuGet 套件管理員,並以灰色醒目提示。

新增 Web API NuGet 套件

安裝 NuGet 套件管理員之後,請將 Web API 自我託管套件新增至您的專案。

  1. 從 [工具] 功能表中選取 [NuGet 套件管理員]附註:如果您沒有看到此功能表項目,請確定 NuGet 套件管理員是否已正確安裝。
  2. 選取 [管理解決方案的 NuGet 套件]
  3. 在 [管理 NugGet 套件] 對話方塊中,選取 [線上]
  4. 在搜尋方塊中,輸入「Microsoft.AspNet.WebApi.SelfHost」。
  5. 選取 [ASP.NET Web API 自我託管套件],然後按一下 [安裝]
  6. 安裝套件之後,按一下 [關閉] 以關閉對話方塊。

注意

請務必安裝名為 Microsoft.AspNet.WebApi.SelfHost 的套件,而不是 AspNetWebApi.SelfHost。

[管理 NuGet 套件] 對話方塊的螢幕擷取畫面,其中顯示 Microsoft ASP .Net Web API 自我託管,並以藍色醒目提示。

建立模型和控制器

本教學課程使用與使用者入門教學課程相同的模型和控制器類別。

新增名為 Product 的公用類別。

namespace SelfHost
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

新增名為 ProductsController 的公用類別。 從 System.Web.Http.ApiController 衍生此類別。

namespace SelfHost
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Web.Http;
    
    public class ProductsController : ApiController
    {
        Product[] products = new Product[]  
        {  
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return product;
        }

        public IEnumerable<Product> GetProductsByCategory(string category)
        {
            return products.Where(p => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}

如需此控制器中程式碼的詳細資訊,請參閱使用者入門教學課程。 此控制器會定義三個 GET 動作:

URI 描述
/api/products 取得所有產品清單。
/api/products/id 依識別碼取得產品。
/api/products/?category=category 依類別取得產品清單。

託管 Web API

開啟 Program.cs 檔案,然後使用陳述式新增下列內容:

using System.Web.Http;
using System.Web.Http.SelfHost;

將下列程式碼新增至 [程式] 類別。

var config = new HttpSelfHostConfiguration("http://localhost:8080");

config.Routes.MapHttpRoute(
    "API Default", "api/{controller}/{id}", 
    new { id = RouteParameter.Optional });

using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
    server.OpenAsync().Wait();
    Console.WriteLine("Press Enter to quit.");
    Console.ReadLine();
}

(選用) 新增 HTTP URL 命名空間保留

此應用程式會接聽 http://localhost:8080/。 根據預設,在特定 HTTP 位址接聽需要系統管理員權限。 因此,當您執行本教學課程時,可能會收到此錯誤:「HTTP 無法註冊 URL」http://+:8080/";有兩種方式可避免此錯誤:

  • 使用已提高的系統管理員權限執行 Visual Studio,或者
  • 使用 Netsh.exe 提供您的帳戶權限來保留 URL。

若要使用 Netsh.exe,請使用系統管理員權限開啟命令提示字元,然後輸入下列命令:

netsh http add urlacl url=http://+:8080/ user=machine\username

其中 machine\username 是您的使用者帳戶。

當您完成自我託管時,請務必刪除保留:

netsh http delete urlacl url=http://+:8080/

從用戶端應用程式呼叫 Web API (C#)

我們來撰寫呼叫 Web API 的簡單主控台應用程式。

將新的主控台應用程式專案新增至解決方案:

  • 在 [方案總管] 中,以滑鼠右鍵按一下解決方案,然後選取 [新增專案]
  • 建立名為「ClientApp」的新主控台應用程式。

方案總管的螢幕擷取畫面,其中顯示以白色醒目提示的 [新增] 和 [新增專案] 右鍵功能表項目。

使用 NuGet 套件管理員新增 ASP.NET Web API Core 程式庫套件:

  • 從 [工具] 功能表中選取 [NuGet 套件管理員]
  • 選取 [管理解決方案的 NuGet 套件]
  • 在 [管理 NuGet 套件] 對話方塊中,選取 [線上]
  • 在搜尋方塊中,輸入「Microsoft.AspNet.WebApi.Client」。
  • 選取 [Microsoft ASP.NET Web API 用戶端程式庫] 套件,然後按一下 [安裝]

將 ClientApp 中的參照新增至 SelfHost 專案:

  • 在 [方案總管] 中,於 ClientApp 專案上按一下滑鼠右鍵。
  • 選取 [新增參考]
  • 在 [參照管理員] 對話方塊的 [方案] 底下,選取 [專案]
  • 選取 SelfHost 專案。
  • 按一下 [確定]

[參照管理員] 對話方塊的螢幕擷取畫面,其中顯示以藍色方塊醒目提示的自我託管專案。

開啟 Client/Program.cs 檔案。 使用 陳述式新增下列內容:

using System.Net.Http;

新增靜態 HttpClient 執行個體:

namespace Client
{
    class Program
    {
        static HttpClient client = new HttpClient();
    }
}

新增下列方法以列出所有產品、依識別碼列出產品,以及依類別列出產品。

static void ListAllProducts()
{
    HttpResponseMessage resp = client.GetAsync("api/products").Result;
    resp.EnsureSuccessStatusCode();

    var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
    foreach (var p in products)
    {
        Console.WriteLine("{0} {1} {2} ({3})", p.Id, p.Name, p.Price, p.Category);
    }
}

static void ListProduct(int id)
{
    var resp = client.GetAsync(string.Format("api/products/{0}", id)).Result;
    resp.EnsureSuccessStatusCode();

    var product = resp.Content.ReadAsAsync<SelfHost.Product>().Result;
    Console.WriteLine("ID {0}: {1}", id, product.Name);
}

static void ListProducts(string category)
{
    Console.WriteLine("Products in '{0}':", category);

    string query = string.Format("api/products?category={0}", category);

    var resp = client.GetAsync(query).Result;
    resp.EnsureSuccessStatusCode();

    var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
    foreach (var product in products)
    {
        Console.WriteLine(product.Name);
    }
}

每個方法都遵循相同的模式:

  1. 呼叫 HttpClient.GetAsync,將 GET 要求傳送至適當的 URI。
  2. 呼叫 HttpResponseMessage.EnsureSuccessStatusCode。 如果 HTTP 回應狀態為錯誤碼,這個方法會擲回例外狀況。
  3. 呼叫 ReadAsAsync<T>,從 HTTP 回應還原序列化 CLR 類型。 此方法是在 System.Net.Http.HttpContentExtensions 中定義的擴充功能方法。

GetAsyncReadAsAsync 方法皆為非同步。 傳回表示非同步作業的工作物件。 取得 Result 屬性會封鎖執行緒,直到作業完成為止。

如需使用 HttpClient 的詳細資訊,包括如何進行非封鎖呼叫,請參閱從 .NET 用戶端呼叫 Web API

呼叫這些方法之前,請將 HttpClient 執行個體上的 BaseAddress 屬性設定為 "http://localhost:8080"。 例如:

static void Main(string[] args)
{
    client.BaseAddress = new Uri("http://localhost:8080");

    ListAllProducts();
    ListProduct(1);
    ListProducts("toys");

    Console.WriteLine("Press Enter to quit.");
    Console.ReadLine();
}

這應該會產生下列輸出。 (請記得先執行 SelfHost 應用程式。)

1 Tomato Soup 1.0 (Groceries)
2 Yo-yo 3.75 (Toys)
3 Hammer 16.99 (Hardware)
ID 1: Tomato Soup
Products in 'toys':
Yo-yo
Press Enter to quit.

主控台視窗的螢幕擷取畫面,其中顯示與識別碼和類別相關聯的已輸出產品清單。