表述性状态转移 (REST) 是一种用于生成 Web 服务的体系结构样式。 REST 请求通常使用 Web 浏览器用于检索网页并将数据发送到服务器的相同 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 服务操作
示例 REST 服务是使用 ASP.NET Core编写的,并提供以下操作:
HTTP 方法
相对 URI
public string ID { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public bool Done { get; set; }
该
ID
属性用于唯一标识每个
TodoItem
对象,并由 Web 服务用来标识要更新或删除的数据。 例如,若要删除
TodoItem
其 ID 为
6bb8a868-dba1-4f1a-93b7-24ebce87e243
,.NET MAUI 应用会向
https://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243
其中发送 DELETE 请求。
当 Web API 框架收到请求时,它会将请求路由到操作。 这些操作是类中的
TodoItemsController
公共方法。 Web API 框架使用路由中间件来匹配传入请求的 URL,并将其映射到操作。 REST API 应使用属性路由将应用的功能建模为一组资源,其操作由 HTTP 谓词表示。 属性路由使用一组属性将操作直接映射到路由模板。 有关属性路由的详细信息,请参阅
REST API 的属性路由
。 有关使用 ASP.NET Core 生成 REST 服务的详细信息,请参阅
为本机移动应用程序创建后端服务
。
创建 HTTPClient 对象
.NET 多平台应用 UI (.NET MAUI) 应用可以通过使用类向 Web 服务发送请求来使用基于 REST 的 Web 服务
HttpClient
。 此类提供从 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 服务接收并发送到 Web 服务的 JSON 有效负载的格式。 有关详细信息,请参阅 如何使用 System.Text.Json 实例化 JsonSerializerOptions 实例。
该方法 HttpClient.GetAsync 用于向 URI 指定的 Web 服务发送 GET 请求,然后从 Web 服务接收响应:
public async Task<List<TodoItem>> RefreshDataAsync()
Items = new List<TodoItem>();
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
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-Type 和 Content-Encoding。 然后,将使用该方法读取stringHttpContent.ReadAsStringAsync内容。 然后,将 string JSON 反序列化为ListTodoItem对象。
ReadAsStringAsync使用此方法检索大型响应可能会对性能产生负面影响。 在这种情况下,应直接反序列化响应,以避免必须完全缓冲它。
该方法 HttpClient.PostAsync 用于向 URI 指定的 Web 服务发送 POST 请求,然后从 Web 服务接收响应:
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
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);
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 用于向 URI 指定的 Web 服务发送 PUT 请求,然后从 Web 服务接收响应:
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
response = await _client.PutAsync(uri, content);
该方法的操作 PutAsync 与 PostAsync 用于在 Web 服务中创建数据的方法相同。 但是,从 Web 服务发送的可能响应有所不同。
REST 服务在其响应中发送 HTTP 状态代码,该代码可从属性获取 HttpResponseMessage.IsSuccessStatusCode ,以指示 HTTP 请求是成功还是失败。 此操作的典型响应包括:
204 (NO CONTENT) – 请求已成功处理,响应有意为空。
400 (BAD REQUEST) – 服务器无法理解请求。
404 (找不到) – 请求的资源不存在于服务器上。
该方法 HttpClient.DeleteAsync 用于向 URI 指定的 Web 服务发送 DELETE 请求,然后从 Web 服务接收响应:
public async Task DeleteTodoItemAsync(string id)
Uri uri = new Uri(string.Format(Constants.RestUrl, id));
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 服务。