自我裝載 ASP.NET Web API 1 (C#)Self-Host ASP.NET Web API 1 (C#)

藉由Mike Wassonby Mike Wasson

本教學課程會示範如何裝載於主控台應用程式的 web API。This tutorial shows how to host a web API inside a console application. ASP.NET Web API 不需要 IIS。ASP.NET Web API does not require IIS. 您可以在您自己的主控件程序中,自我裝載的 web API。You can self-host a web API in your own host process.

新的應用程式應該使用 OWIN 自我裝載 Web API。New applications should use OWIN to self-host Web API. 請參閱使用 OWIN 自我裝載 ASP.NET Web API 2See Use OWIN to Self-Host ASP.NET Web API 2.

在本教學課程中使用的軟體版本Software versions used in the tutorial

  • Web API 1Web API 1
  • Visual Studio 2012Visual Studio 2012

建立主控台應用程式專案Create the Console Application Project

啟動 Visual Studio,然後選取新的專案開始頁面。Start Visual Studio and select New Project from the Start page. 或從檔案功能表上,選取新增,然後專案Or, from the File menu, select New and then Project.

範本窗格中,選取已安裝的範本展開Visual C# 節點。In the Templates pane, select Installed Templates and expand the Visual C# node. 底下Visual C#,選取WindowsUnder Visual C#, select Windows. 在專案範本清單中,選取主控台應用程式In the list of project templates, select Console Application. 將專案命名為"SelfHost"然後按一下確定Name the project "SelfHost" and click OK.

設定目標架構 (Visual Studio 2010)Set the Target Framework (Visual Studio 2010)

如果您使用 Visual Studio 2010,將.NET Framework 4.0 目標 framework。If you are using Visual Studio 2010, change the target framework to .NET Framework 4.0. (根據預設,專案範本的目標.Net Framework Client Profile。)(By default, the project template targets the .Net Framework Client Profile.)

在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取屬性In Solution Explorer, right-click the project and select Properties. 目標 framework下拉式清單中,將目標 framework 變更為.NET Framework 4.0。In the Target framework dropdown list, change the target framework to .NET Framework 4.0. 當出現提示,以套用變更,請按一下When prompted to apply the change, click Yes.

安裝 NuGet 套件管理員Install NuGet Package Manager

NuGet 套件管理員是最簡單的方式,將 Web API 組件新增至非 ASP.NET 專案。The NuGet Package Manager is the easiest way to add the Web API assemblies to a non-ASP.NET project.

若要檢查是否已安裝 NuGet 套件管理員,請按一下工具Visual Studio 中的功能表。To check if NuGet Package Manager is installed, click the Tools menu in Visual Studio. 如果您看到的功能表項目呼叫NuGet 套件管理員,則您可以 NuGet 套件管理員。If you see a menu item called NuGet Package Manager, then you have NuGet Package Manager.

若要安裝 NuGet 套件管理員:To install NuGet Package Manager:

  1. 啟動 Visual Studio。Start Visual Studio.
  2. 工具功能表上,選取擴充功能和更新From the Tools menu, select Extensions and Updates.
  3. 擴充功能和更新對話方塊中,選取線上In the Extensions and Updates dialog, select Online.
  4. 如果您沒有看到 [NuGet 套件管理員],請在搜尋方塊中輸入 「 nuget 封裝管理員 」。If you don't see "NuGet Package Manager", type "nuget package manager" in the search box.
  5. 選取 NuGet 套件管理員,然後按一下下載Select the NuGet Package Manager and click Download.
  6. 下載完成之後,系統會提示您安裝。After the download completes, you will be prompted to install.
  7. 安裝完成之後,您可能會提示重新啟動 Visual Studio。After the installation completes, you might be prompted to restart Visual Studio.

新增 Web API NuGet 套件Add the Web API NuGet Package

NuGet 套件管理員安裝之後,將 Web API 的自我裝載封裝加入專案。After NuGet Package Manager is installed, add the Web API Self-Host package to your project.

  1. 工具功能表上,選取NuGet 套件管理員From the Tools menu, select NuGet Package Manager. 注意:如果您不會看到此功能表項目,請確定已正確安裝該 NuGet 套件管理員。Note: If do you not see this menu item, make sure that NuGet Package Manager installed correctly.
  2. 選取管理方案的 NuGet 套件Select Manage NuGet Packages for Solution
  3. 管理 Nuget 封裝對話方塊中,選取線上In the Manage NugGet Packages dialog, select Online.
  4. 在 [搜尋] 方塊中,輸入"Microsoft.AspNet.WebApi.SelfHost"。In the search box, type "Microsoft.AspNet.WebApi.SelfHost".
  5. 選取 ASP.NET Web API 自助主應用程式封裝,然後按一下安裝Select the ASP.NET Web API Self Host package and click Install.
  6. 套件會安裝之後,請按一下關閉以關閉對話方塊。After the package installs, click Close to close the dialog.

Note

請務必安裝名為 Microsoft.AspNet.WebApi.SelfHost,不 AspNetWebApi.SelfHost 的套件。Make sure to install the package named Microsoft.AspNet.WebApi.SelfHost, not AspNetWebApi.SelfHost.

建立模型和控制器Create the Model and Controller

本教學課程使用相同的模型和控制器類別作為開始使用教學課程。This tutorial uses the same model and controller classes as the Getting Started tutorial.

新增名為公用類別ProductAdd a public class named 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; }
    }
}

新增名為公用類別ProductsControllerAdd a public class named ProductsController. 從這個類別的衍生System.Web.Http.ApiControllerDerive this class from 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));
        }
    }
}

如需有關此控制器中的程式碼的詳細資訊,請參閱開始使用教學課程。For more information about the code in this controller, see the Getting Started tutorial. 此控制器會定義三個 GET 動作:This controller defines three GET actions:

URIURI 描述Description
/api/products/api/products 取得所有產品的清單。Get a list of all products.
/api/products/id/api/products/id 取得產品的識別碼。Get a product by ID.
/api/products/?category=category/api/products/?category=category 依類別取得產品的清單。Get a list of products by category.

裝載 Web APIHost the Web API

開啟 Program.cs 檔案並新增下列 using 陳述式:Open the file Program.cs and add the following using statements:

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

將下列程式碼加入程式類別。Add the following code to the Program class.

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 命名空間保留區(Optional) Add an HTTP URL Namespace Reservation

此應用程式接聽http://localhost:8080/This application listens to http://localhost:8080/. 根據預設,在特定的 HTTP 位址上進行接聽要求系統管理員權限。By default, listening at a particular HTTP address requires administrator privileges. 當您執行本教學課程時,因此,您可能會收到此錯誤:「 HTTP 無法登錄 URL http://+:8080/」 有兩種方式可避免這個錯誤:When you run the tutorial, therefore, you may get this error: "HTTP could not register URL http://+:8080/" There are two ways to avoid this error:

  • 提高權限的系統管理員權限,以執行 Visual Studio 或Run Visual Studio with elevated administrator permissions, or
  • 您可以使用 Netsh.exe,讓您的帳戶權限,來保留 URL。Use Netsh.exe to give your account permissions to reserve the URL.

若要使用 Netsh.exe,以系統管理員權限開啟命令提示字元並輸入下列命令: 下列命令:To use Netsh.exe, open a command prompt with administrator privileges and enter the following command:following command:

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

何處machine\username是您的使用者帳戶。where machine\username is your user account.

當您完成自我裝載時,請務必刪除保留區:When you are finished self-hosting, be sure to delete the reservation:

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

呼叫 Web API,從用戶端應用程式 (C#)Call the Web API from a Client Application (C#)

讓我們撰寫會呼叫 web API 的簡單主控台應用程式。Let's write a simple console application that calls the web API.

將新的主控台應用程式專案加入方案:Add a new console application project to the solution:

  • 在 [方案總管] 中,以滑鼠右鍵按一下方案,然後選取加入新的專案In Solution Explorer, right-click the solution and select Add New Project.
  • 建立新的主控台應用程式,名為"ClientApp"。Create a new console application named "ClientApp".

使用 NuGet 套件管理員來新增 ASP.NET Web API 核心程式庫套件:Use NuGet Package Manager to add the ASP.NET Web API Core Libraries package:

  • 從 [工具] 功能表中,選取NuGet 套件管理員From the Tools menu, select NuGet Package Manager.
  • 選取管理方案的 NuGet 套件Select Manage NuGet Packages for Solution
  • 管理 NuGet 套件對話方塊中,選取線上In the Manage NuGet Packages dialog, select Online.
  • 在 [搜尋] 方塊中,輸入"Microsoft.AspNet.WebApi.Client"。In the search box, type "Microsoft.AspNet.WebApi.Client".
  • 選取 Microsoft ASP.NET Web API 用戶端程式庫套件,然後按一下安裝Select the Microsoft ASP.NET Web API Client Libraries package and click Install.

在 ClientApp 加入 SelfHost 專案的參考:Add a reference in ClientApp to the SelfHost project:

  • 在 [方案總管] 中,以滑鼠右鍵按一下 ClientApp 專案。In Solution Explorer, right-click the ClientApp project.
  • 選取 [新增參考]。Select Add Reference.
  • 在 [參考管理員] 對話方塊底下解決方案,選取專案In the Reference Manager dialog, under Solution, select Projects.
  • 選取 SelfHost 專案。Select the SelfHost project.
  • 按一下 [確定] 。Click OK.

開啟 Client/Program.cs 檔案。Open the Client/Program.cs file. 新增下列使用陳述式:Add the following using statement:

using System.Net.Http;

新增靜態HttpClient執行個體:Add a static HttpClient instance:

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

新增下列方法來依類別列出所有產品清單的識別碼、 產品和產品清單。Add the following methods to list all products, list a product by ID, and list products by category.

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);
    }
}

每一種方法都遵循相同的模式:Each of these methods follows the same pattern:

  1. 呼叫HttpClient.GetAsync將 GET 要求傳送至適當的 URI。Call HttpClient.GetAsync to send a GET request to the appropriate URI.
  2. 呼叫HttpResponseMessage.EnsureSuccessStatusCodeCall HttpResponseMessage.EnsureSuccessStatusCode. 如果 HTTP 回應狀態錯誤碼,則這個方法會擲回例外狀況。This method throws an exception if the HTTP response status is an error code.
  3. 呼叫ReadAsAsync<T> 還原序列化的 HTTP 回應中的 CLR 型別。Call ReadAsAsync<T> to deserialize a CLR type from the HTTP response. 這個方法是擴充方法,定義於System.Net.Http.HttpContentExtensionsThis method is an extension method, defined in System.Net.Http.HttpContentExtensions.

GetAsyncReadAsAsync方法為非同步。The GetAsync and ReadAsAsync methods are both asynchronous. 它們會傳回任務代表非同步作業的物件。They return Task objects that represent the asynchronous operation. 取得結果屬性會封鎖執行緒直到作業完成為止。Getting the Result property blocks the thread until the operation completes.

如需有關使用 HttpClient,包括如何建立非封鎖式呼叫,請參閱 < 呼叫 Web API 從.NET 用戶端For more information about using HttpClient, including how to make non-blocking calls, see Calling a Web API From a .NET Client.

之前呼叫這些方法,設定 HttpClient 執行個體上的 BaseAddress 屬性 「http://localhost:8080"。Before calling these methods, set the BaseAddress property on the HttpClient instance to "http://localhost:8080". 例如: For example:

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();
}

這應輸出下列項目。This should output the following. (請記得先執行 SelfHost 應用程式。)(Remember to run the SelfHost application first.)

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.