使用 RESTful Web 服務Consume a RESTful Web Service

下載範例 下載範例Download Sample Download the sample

將 web 服務整合到應用程式是常見的案例。本文示範如何從 Xamarin 應用程式使用 RESTful web 服務。Integrating a web service into an application is a common scenario. This article demonstrates how to consume a RESTful web service from a Xamarin.Forms application.

具像狀態傳輸(REST)是用來建立 web 服務的架構樣式。Representational State Transfer (REST) is an architectural style for building web services. REST 要求是使用 web 瀏覽器用來抓取網頁和將資料傳送到伺服器的相同 HTTP 動詞,透過 HTTP 進行。REST requests are made over HTTP using the same HTTP verbs that web browsers use to retrieve web pages and to send data to servers. 動詞:The verbs are:

  • GET –這是用來從 web 服務抓取資料的作業。GET – this operation is used to retrieve data from the web service.
  • POST –這項作業會用來在 web 服務上建立新的資料項目目。POST – this operation is used to create a new item of data on the web service.
  • PUT –此作業用來更新 web 服務上的資料項目。PUT – this operation is used to update an item of data on the web service.
  • 修補程式–這項作業是用來更新 web 服務上的資料項目,方法是描述有關如何修改專案的一組指示。PATCH – this operation is used to update an item of data on the web service by describing a set of instructions about how the item should be modified. 範例應用程式中不會使用這個動詞。This verb is not used in the sample application.
  • Delete –此作業用來刪除 web 服務上的資料項目。DELETE – this operation is used to delete an item of data on the web service.

遵守 REST 的 Web 服務 Api 稱為 RESTful Api,並使用來定義:Web service APIs that adhere to REST are called RESTful APIs, and are defined using:

  • 基底 URI。A base URI.
  • HTTP 方法,例如 GET、POST、PUT、PATCH 或 DELETE。HTTP methods, such as GET, POST, PUT, PATCH, or DELETE.
  • 資料的媒體類型,例如 JavaScript 物件標記法(JSON)。A media type for the data, such as JavaScript Object Notation (JSON).

RESTful web 服務通常會使用 JSON 訊息將資料傳回給用戶端。RESTful web services typically use JSON messages to return data to the client. JSON 是以文字為基礎的資料交換格式,會產生 compact 承載,這會導致傳送資料時的頻寬需求降低。JSON is a text-based data-interchange format that produces compact payloads, which results in reduced bandwidth requirements when sending data. 範例應用程式會使用開放原始碼NewtonSoft JSON.NET 程式庫來序列化和還原序列化訊息。The sample application uses the open source NewtonSoft JSON.NET library to serialize and deserialize messages.

REST 的簡單性讓它成為在行動應用程式中存取 web 服務的主要方法。The simplicity of REST has helped make it the primary method for accessing web services in mobile applications.

執行範例應用程式時,它會連接到本機裝載的 REST 服務,如下列螢幕擷取畫面所示:When the sample application is run, it will connect to a locally hosted REST service, as shown in the following screenshot:

注意

在 iOS 9 和更新版本中,應用程式傳輸安全性(ATS)會強制執行網際網路資源(例如應用程式的後端伺服器)與應用程式之間的安全連線,藉此防止意外洩漏機密資訊。In iOS 9 and greater, App Transport Security (ATS) enforces secure connections between internet resources (such as the app's back-end server) and the app, thereby preventing accidental disclosure of sensitive information. 由於預設會在針對 iOS 9 建立的應用程式中啟用 ATS,因此所有連線都將受限於 ATS 安全性需求。Since ATS is enabled by default in apps built for iOS 9, all connections will be subject to ATS security requirements. 如果連線不符合這些需求,則會失敗並產生例外狀況。If connections do not meet these requirements, they will fail with an exception.

如果無法使用HTTPS通訊協定和網際網路資源的安全通訊,可以退出宣告 ATS。ATS can be opted out of if it is not possible to use the HTTPS protocol and secure communication for internet resources. 這可以藉由更新應用程式的plist檔案來達成。This can be achieved by updating the app's Info.plist file. 如需詳細資訊,請參閱應用程式傳輸安全性For more information see App Transport Security.

使用 Web 服務Consuming the Web Service

REST 服務是使用 ASP.NET Core 撰寫的,並提供下列作業:The REST service is written using ASP.NET Core and provides the following operations:

運算Operation HTTP 方法HTTP method 相對 URIRelative URI 參數Parameters
取得待辦事項的清單Get a list of to-do items GETGET /api/todoitems//api/todoitems/
建立新的待辦事項專案Create a new to-do item POSTPOST /api/todoitems//api/todoitems/ JSON 格式的 TodoItemA JSON formatted TodoItem
更新待辦事項Update a to-do item 提出PUT /api/todoitems//api/todoitems/ JSON 格式的 TodoItemA JSON formatted TodoItem
刪除待辦事項Delete a to-do item DeleteDELETE /api/todoitems/{id}/api/todoitems/{id}

大部分的 Uri 都包含路徑中的 TodoItem 識別碼。The majority of the URIs include the TodoItem ID in the path. 例如,若要刪除識別碼為 6bb8a868-dba1-4f1a-93b7-24ebce87e243TodoItem,用戶端會將刪除要求傳送至 http://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243For example, to delete the TodoItem whose ID is 6bb8a868-dba1-4f1a-93b7-24ebce87e243, the client sends a DELETE request to http://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243. 如需範例應用程式中所使用之資料模型的詳細資訊,請參閱模型化資料For more information about the data model used in the sample application, see Modeling the data.

當 Web API 架構收到要求時,它會將要求路由傳送至動作。When the Web API framework receives a request it routes the request to an action. 這些動作只是 TodoItemsController 類別中的公用方法。These actions are simply public methods in the TodoItemsController class. 架構會使用路由表來判斷要叫用哪個動作以回應要求,如下列程式碼範例所示:The framework uses a routing table to determine which action to invoke in response to a request, which is shown in the following code example:

config.Routes.MapHttpRoute(
    name: "TodoItemsApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { controller="todoitems", id = RouteParameter.Optional }
);

路由表包含路由範本,而當 Web API 架構收到 HTTP 要求時,它會嘗試比對路由表中的路由範本與 URI。The routing table contains a route template, and when the Web API framework receives an HTTP request, it tries to match the URI against the route template in the routing table. 如果找不到相符的路由,用戶端會收到404(找不到)錯誤。If a matching route cannot be found the client receives a 404 (not found) error. 如果找到相符的路由,Web API 會選取控制器和動作,如下所示:If a matching route is found, Web API selects the controller and the action as follows:

  • 若要尋找控制器,Web API 會將 "controller" 新增至 {controller} 變數的值。To find the controller, Web API adds "controller" to the value of the {controller} variable.
  • 若要尋找此動作,Web API 會查看 HTTP 方法,並查看使用與屬性相同的 HTTP 方法裝飾的控制器動作。To find the action, Web API looks at the HTTP method and looks at controller actions that are decorated with the same HTTP method as an attribute.
  • {Id} 預留位置變數會對應至動作參數。The {id} placeholder variable is mapped to an action parameter.

REST 服務會使用基本驗證。The REST service uses basic authentication. 如需詳細資訊,請參閱驗證 RESTful web 服務For more information see Authenticating a RESTful web service. 如需有關 ASP.NET Web API 路由的詳細資訊,請參閱 ASP.NET 網站上ASP.NET Web API 中的路由For more information about ASP.NET Web API routing, see Routing in ASP.NET Web API on the ASP.NET website. 如需使用 ASP.NET Core 建立 REST 服務的詳細資訊,請參閱建立原生行動應用程式的後端服務For more information about building the REST service using ASP.NET Core, see Creating Backend Services for Native Mobile Applications.

HttpClient 類別是用來透過 HTTP 傳送和接收要求。The HttpClient class is used to send and receive requests over HTTP. 它提供的功能可用於傳送 HTTP 要求,以及從 URI 識別的資源接收 HTTP 回應。It provides functionality for sending HTTP requests and receiving HTTP responses from a URI identified resource. 每個要求都會以非同步作業的方式傳送。Each request is sent as an asynchronous operation. 如需非同步作業的詳細資訊,請參閱非同步支援總覽For more information about asynchronous operations, see Async Support Overview.

HttpResponseMessage 類別代表在提出 HTTP 要求之後,從 web 服務接收的 HTTP 回應訊息。The HttpResponseMessage class represents an HTTP response message received from the web service after an HTTP request has been made. 其中包含回應的相關資訊,包括狀態碼、標頭和任何主體。It contains information about the response, including the status code, headers, and any body. HttpContent 類別代表 HTTP 主體和內容標頭,例如 Content-TypeContent-EncodingThe HttpContent class represents the HTTP body and content headers, such as Content-Type and Content-Encoding. 您可以使用任何 ReadAs 方法(例如 ReadAsStringAsyncReadAsByteArrayAsync)來讀取內容,視資料的格式而定。The content can be read using any of the ReadAs methods, such as ReadAsStringAsync and ReadAsByteArrayAsync, depending upon the format of the data.

建立 HTTPClient 物件Creating the HTTPClient Object

HttpClient 實例是在類別層級宣告,因此,只要應用程式需要提出 HTTP 要求,物件就會存在,如下列程式碼範例所示:The HttpClient instance is declared at the class-level so that the object lives for as long as the application needs to make HTTP requests, as shown in the following code example:

public class RestService : IRestService
{
  HttpClient _client;
  ...

  public RestService ()
  {
    _client = new HttpClient ();
  }
  ...
}

擷取資料Retrieving Data

HttpClient.GetAsync 方法是用來將 GET 要求傳送至 URI 所指定的 web 服務,然後接收來自 web 服務的回應,如下列程式碼範例所示:The HttpClient.GetAsync method is used to send the GET request to the web service specified by the URI, and then receive the response from the web service, as shown in the following code example:

public async Task<List<TodoItem>> RefreshDataAsync ()
{
  ...
  var uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));
  ...
  var response = await _client.GetAsync (uri);
  if (response.IsSuccessStatusCode)
  {
      var content = await response.Content.ReadAsStringAsync ();
      Items = JsonConvert.DeserializeObject <List<TodoItem>> (content);
  }
  ...
}

REST 服務會在 HttpResponseMessage.IsSuccessStatusCode 屬性中傳送 HTTP 狀態碼,以指出 HTTP 要求成功或失敗。The REST service sends an HTTP status code in the HttpResponseMessage.IsSuccessStatusCode property, to indicate whether the HTTP request succeeded or failed. 在這項作業中,REST 服務會在回應中傳送 HTTP 狀態碼200(確定),這表示要求成功,且要求的資訊在回應中。For this operation the REST service sends HTTP status code 200 (OK) in the response, which indicates that the request succeeded and that the requested information is in the response.

如果 HTTP 作業成功,則會讀取回應的內容,以供顯示。If the HTTP operation was successful, the content of the response is read, for display. HttpResponseMessage.Content 屬性代表 HTTP 回應的內容,而 HttpContent.ReadAsStringAsync 方法會以非同步方式將 HTTP 內容寫入字串。The HttpResponseMessage.Content property represents the content of the HTTP response, and the HttpContent.ReadAsStringAsync method asynchronously writes the HTTP content to a string. 然後,此內容會從 JSON 轉換成 TodoItem 實例的 ListThis content is then converted from JSON to a List of TodoItem instances.

建立資料Creating Data

HttpClient.PostAsync 方法是用來將 POST 要求傳送至 URI 所指定的 web 服務,然後接收來自 web 服務的回應,如下列程式碼範例所示:The HttpClient.PostAsync method is used to send the POST request to the web service specified by the URI, and then to receive the response from the web service, as shown in the following code example:

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  var uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));

  ...
  var json = JsonConvert.SerializeObject (item);
  var content = new StringContent (json, Encoding.UTF8, "application/json");

  HttpResponseMessage response = null;
  if (isNewItem)
  {
    response = await _client.PostAsync (uri, content);
  }
  ...

  if (response.IsSuccessStatusCode)
  {
    Debug.WriteLine (@"\tTodoItem successfully saved.");

  }
  ...
}

TodoItem 實例會轉換成 JSON 承載,以傳送至 web 服務。The TodoItem instance is converted to a JSON payload for sending to the web service. 然後,此承載會內嵌于 HTTP 內容的主體中,在使用 PostAsync 方法提出要求之前,將會傳送至 web 服務。This payload is then embedded in the body of the HTTP content that will be sent to the web service before the request is made with the PostAsync method.

REST 服務會在 HttpResponseMessage.IsSuccessStatusCode 屬性中傳送 HTTP 狀態碼,以指出 HTTP 要求成功或失敗。The REST service sends an HTTP status code in the HttpResponseMessage.IsSuccessStatusCode property, to indicate whether the HTTP request succeeded or failed. 這種作業的常見回應為:The common responses for this operation are:

  • 201 (已建立) –要求導致在傳送回應之前建立新的資源。201 (CREATED) – the request resulted in a new resource being created before the response was sent.
  • 400 (不正確的要求) -伺服器無法理解要求。400 (BAD REQUEST) – the request is not understood by the server.
  • 409 (衝突) -無法執行要求,因為伺服器上發生衝突。409 (CONFLICT) – the request could not be carried out because of a conflict on the server.

更新資料Updating Data

HttpClient.PutAsync 方法是用來將 PUT 要求傳送至 URI 所指定的 web 服務,然後接收來自 web 服務的回應,如下列程式碼範例所示:The HttpClient.PutAsync method is used to send the PUT request to the web service specified by the URI, and then receive the response from the web service, as shown in the following code example:

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  ...
  response = await _client.PutAsync (uri, content);
  ...
}

PutAsync 方法的作業與用來在 web 服務中建立資料的 PostAsync 方法相同。The operation of the PutAsync method is identical to the PostAsync method that's used for creating data in the web service. 不過,從 web 服務傳送的可能回應會有所不同。However, the possible responses sent from the web service differ.

REST 服務會在 HttpResponseMessage.IsSuccessStatusCode 屬性中傳送 HTTP 狀態碼,以指出 HTTP 要求成功或失敗。The REST service sends an HTTP status code in the HttpResponseMessage.IsSuccessStatusCode property, to indicate whether the HTTP request succeeded or failed. 這種作業的常見回應為:The common responses for this operation are:

  • 204 (沒有內容) –已成功處理要求,而且回應是刻意為空白。204 (NO CONTENT) – the request has been successfully processed and the response is intentionally blank.
  • 400 (不正確的要求) -伺服器無法理解要求。400 (BAD REQUEST) – the request is not understood by the server.
  • 404 (找不到) -要求的資源不存在於伺服器上。404 (NOT FOUND) – the requested resource does not exist on the server.

刪除資料Deleting Data

HttpClient.DeleteAsync 方法是用來將 DELETE 要求傳送至 URI 所指定的 web 服務,然後接收來自 web 服務的回應,如下列程式碼範例所示:The HttpClient.DeleteAsync method is used to send the DELETE request to the web service specified by the URI, and then receive the response from the web service, as shown in the following code example:

public async Task DeleteTodoItemAsync (string id)
{
  var uri = new Uri (string.Format (Constants.TodoItemsUrl, id));
  ...
  var response = await _client.DeleteAsync (uri);
  if (response.IsSuccessStatusCode)
  {
    Debug.WriteLine (@"\tTodoItem successfully deleted.");
  }
  ...
}

REST 服務會在 HttpResponseMessage.IsSuccessStatusCode 屬性中傳送 HTTP 狀態碼,以指出 HTTP 要求成功或失敗。The REST service sends an HTTP status code in the HttpResponseMessage.IsSuccessStatusCode property, to indicate whether the HTTP request succeeded or failed. 這種作業的常見回應為:The common responses for this operation are:

  • 204 (沒有內容) –已成功處理要求,而且回應是刻意為空白。204 (NO CONTENT) – the request has been successfully processed and the response is intentionally blank.
  • 400 (不正確的要求) -伺服器無法理解要求。400 (BAD REQUEST) – the request is not understood by the server.
  • 404 (找不到) -要求的資源不存在於伺服器上。404 (NOT FOUND) – the requested resource does not exist on the server.