共用方式為


取用 REST 型 Web 服務

Browse sample. 流覽範例

具象狀態傳輸 (REST) 是建立 Web 服務的架構樣式。 REST 要求通常是使用網頁瀏覽器用來擷取網頁並將數據傳送至伺服器的相同 HTTP 動詞,透過 HTTPS 進行。 指令動詞如下:

  • GET - 這項作業用來從 Web 服務取出資料。
  • POST - 這項作業用來在 Web 服務上建立新的資料項目。
  • PUT - 這項作業用來在 Web 服務上更新資料項目。
  • PATCH - 這項作業用來透過描述有關應該如何修改項目的一組指示,更新 Web 服務上的資料項目。
  • DELETE - 這項作業用來在 Web 服務上刪除資料項目。

遵守 REST 的 Web 服務 API 會使用下列方式定義:

  • 基底 URI。
  • HTTP 方法,例如 GET、POST、PUT、PATCH 或 DELETE。
  • 數據的媒體類型,例如 JavaScript 物件表示法(JSON)。

REST 型 Web 服務通常會使用 JSON 訊息將數據傳回用戶端。 JSON 是一種以文字為基礎的數據交換格式,會產生精簡承載,這會導致傳送數據時帶寬需求降低。 REST 的簡單性有助於它成為在行動應用程式中存取 Web 服務的主要方法。

注意

存取 Web 服務通常需要異步程序設計。 如需異步程式設計的詳細資訊,請參閱 使用 async 和 await 進行異步程序設計。

Web 服務作業

範例 REST 服務是使用 ASP.NET Core 撰寫,並提供下列作業:

作業 HTTP 方法 相對 URI 參數
取得 Todo 項目清單 GET /api/todoitems/
建立新的 Todo 專案 POST /api/todoitems/ JSON 格式化的 TodoItem
更新 todo 專案 PUT /api/todoitems/ JSON 格式化的 TodoItem
刪除 todo 專案 DELETE /api/todoitems/{id}

.NET MAUI 應用程式和 Web 服務會 TodoItem 使用 類別來建立顯示並傳送至 Web 服務以儲存的數據模型:

public class TodoItem
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Notes { get; set; }
    public bool Done { get; set; }
}

屬性 ID 可用來唯一識別每個 TodoItem 物件,並由 Web 服務用來識別要更新或刪除的數據。 例如,若要刪除 TodoItem 識別碼為 6bb8a868-dba1-4f1a-93b7-24ebce87e243的 ,.NET MAUI 應用程式會將 DELETE 要求傳送至 https://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243

當 Web API 架構收到要求時,它會將要求路由傳送至動作。 這些動作是類別中的 TodoItemsController 公用方法。 Web API 架構會使用路由中間件來比對傳入要求的URL,並將其對應至動作。 REST API 應該使用屬性路由,將應用程式的功能模型化為一組資源,其作業是以 HTTP 動詞表示。 屬性路由使用一組屬性,將動作直接對應至路由範本。 如需屬性路由的詳細資訊,請參閱 REST API 的屬性路由。 如需使用 ASP.NET Core 建置 REST 服務的詳細資訊,請參閱 建立原生行動應用程式的後端服務。

建立 HTTPClient 物件

.NET 多平台應用程式 UI (.NET MAUI) 應用程式可以使用 類別將要求傳送至 Web 服務,以取用 HttpClient REST 型 Web 服務。 這個類別提供從 URI 識別資源傳送 HTTP 要求和接收 HTTP 回應的功能。 每個要求都會以異步操作的形式傳送。

HttpClient物件應該在類別層級宣告,以便只要應用程式需要提出 HTTP 要求即可存留:

public class RestService
{
    HttpClient _client;
    JsonSerializerOptions _serializerOptions;

    public List<TodoItem> Items { get; private set; }

    public RestService()
    {
        _client = new HttpClient();
        _serializerOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        };
    }
    ...
}

對象 JsonSerializerOptions 可用來設定從 接收並傳送至 Web 服務的 JSON 承載格式設定。 如需詳細資訊,請參閱 如何使用 System.Text.Json 具現化 JsonSerializerOptions 實例。

取出資料

方法 HttpClient.GetAsync 可用來將 GET 要求傳送至 URI 所指定的 Web 服務,然後接收來自 Web 服務的回應:

public async Task<List<TodoItem>> RefreshDataAsync()
{
    Items = new List<TodoItem>();

    Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
    try
    {
        HttpResponseMessage response = await _client.GetAsync(uri);
        if (response.IsSuccessStatusCode)
        {
            string content = await response.Content.ReadAsStringAsync();
            Items = JsonSerializer.Deserialize<List<TodoItem>>(content, _serializerOptions);
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"\tERROR {0}", ex.Message);
    }

    return Items;
}

數據會以物件的形式從 Web 服務 HttpResponseMessage 接收。 其中包含回應的相關信息,包括狀態代碼、標頭和任何本文。 REST 服務會在其回應中傳送 HTTP 狀態代碼,其可從 屬性取得 HttpResponseMessage.IsSuccessStatusCode ,以指出 HTTP 要求成功或失敗。 針對這項作業,REST 服務會在回應中傳送 HTTP 狀態代碼 200 (OK),這表示要求成功,且要求的資訊位於回應中。

如果 HTTP 作業成功,則會讀取回應的內容。 屬性 HttpResponseMessage.Content 代表回應的內容,且的類型 HttpContent為 。 類別 HttpContent 代表 HTTP 主體和內容標頭,例如 Content-TypeContent-Encoding。 接著會使用 HttpContent.ReadAsStringAsync 方法將內容讀入 string 。 然後,會 string 從 JSON 還原串行化為 List 物件的 TodoItem

警告

ReadAsStringAsync使用方法來擷取大型回應可能會對效能造成負面影響。 在這種情況下,應該直接還原串行化回應,以避免必須完全緩衝處理它。

建立資料

方法 HttpClient.PostAsync 可用來將 POST 要求傳送至 URI 所指定的 Web 服務,然後接收來自 Web 服務的回應:

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

    try
    {
        string json = JsonSerializer.Serialize<TodoItem>(item, _serializerOptions);
        StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

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

        if (response.IsSuccessStatusCode)
            Debug.WriteLine(@"\tTodoItem successfully saved.");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"\tERROR {0}", ex.Message);
    }
}

在此範例中 TodoItem ,實例會串行化為 JSON 承載,以傳送至 Web 服務。 接著,此承載會內嵌在 HTTP 內容的主體中,該內容會在使用 PostAsync 方法提出要求之前傳送至 Web 服務。

REST 服務會在其回應中傳送 HTTP 狀態代碼,其可從 屬性取得 HttpResponseMessage.IsSuccessStatusCode ,以指出 HTTP 要求成功或失敗。 此作業的一般回應如下:

  • 201 (CREATED) – 要求會導致在傳送回應之前建立新的資源。
  • 400 (BAD REQUEST) - 伺服器無法理解要求。
  • 409 (CONFLICT) - 因為伺服器上的衝突,所以無法執行要求。

更新資料

方法 HttpClient.PutAsync 可用來將 PUT 要求傳送至 URI 所指定的 Web 服務,然後接收來自 Web 服務的回應:

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

方法的 PutAsync 作業與用來在 Web 服務中建立數據的方法相同 PostAsync 。 不過,從 Web 服務傳送的可能回應會有所不同。

REST 服務會在其回應中傳送 HTTP 狀態代碼,其可從 屬性取得 HttpResponseMessage.IsSuccessStatusCode ,以指出 HTTP 要求成功或失敗。 此作業的一般回應如下:

  • 204 (NO CONTENT) – 要求已成功處理,且回應刻意為空白。
  • 400 (BAD REQUEST) - 伺服器無法理解要求。
  • 404 (找不到) - 要求的資源不存在於伺服器上。

刪除資料

方法 HttpClient.DeleteAsync 可用來將 DELETE 要求傳送至 URI 所指定的 Web 服務,然後接收來自 Web 服務的回應:

public async Task DeleteTodoItemAsync(string id)
{
    Uri uri = new Uri(string.Format(Constants.RestUrl, id));

    try
    {
        HttpResponseMessage response = await _client.DeleteAsync(uri);
        if (response.IsSuccessStatusCode)
            Debug.WriteLine(@"\tTodoItem successfully deleted.");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"\tERROR {0}", ex.Message);
    }
}

REST 服務會在其回應中傳送 HTTP 狀態代碼,其可從 屬性取得 HttpResponseMessage.IsSuccessStatusCode ,以指出 HTTP 要求成功或失敗。 此作業的一般回應如下:

  • 204 (NO CONTENT) – 要求已成功處理,且回應刻意為空白。
  • 400 (BAD REQUEST) - 伺服器無法理解要求。
  • 404 (找不到) - 要求的資源不存在於伺服器上。

本機開發

如果您要使用 ASP.NET Core Web API 等架構在本機開發 REST Web 服務,您可以同時對 Web 服務和 .NET MAUI 應用程式進行偵錯。 在此案例中,若要從 Android 模擬器和 iOS 模擬器透過 HTTP 取用 Web 服務,您必須在 .NET MAUI 應用程式中啟用純文字 HTTP 流量。 如需詳細資訊,請參閱從 Android 模擬器和 iOS 模擬器 連線 至本機 Web 服務。