使用 ASP.NET Core 为本机移动应用创建后端服务 您所在的位置:网站首页 vb开发手机app 使用 ASP.NET Core 为本机移动应用创建后端服务

使用 ASP.NET Core 为本机移动应用创建后端服务

2024-07-08 06:49| 来源: 网络整理| 查看: 265

使用 ASP.NET Core 为本机移动应用创建后端服务 项目04/23/2024

作者:James Montemagno

移动应用可与 ASP.NET Core 后端服务通信。 有关从 iOS 模拟器和 Android 仿真程序连接本地 Web 服务的说明,请参阅从 iOS 模拟器和 Android 仿真程序连接到本地 Web 服务。

查看或下载后端服务代码示例

本机移动应用示例

本教程演示如何使用 ASP.NET Core 创建后端服务,以支持本机移动应用。 它使用 Xamarin.Forms TodoRest 应用作为其本机客户端,其中包括 Android、iOS、Windows 的单独本机客户端。 你可以遵循链接中的教程来创建本机应用(并安装必要的免费 Xamarin 工具),以及下载 Xamarin 示例解决方案。 Xamarin 示例包含一个 ASP.NET Core Web API 服务项目,使用本文中的 ASP.NET Core 应用替换(客户端无需进行任何更改)。

功能

TodoREST 应用支持列出、添加、删除和更新待办事项。 每个项都有一个 ID、 Name(名称)、Notes(说明)以及一个指示该项是否已完成的属性 Done。

在上一示例中,项目的主视图列出了每个项的名称,并使用复选标记指示其是否已完成。

点击 + 图标打开“添加项”对话框:

点击主列表屏幕上的项将打开一个编辑对话框,在其中可以修改项的名称、 说明以及是否完成,或删除项目:

若要使用在你计算机上运行的下一节创建的 ASP.NET Core 应用对其进行测试,请更新应用的 RestUrl 常量。

Android 模拟器不在本地计算机上运行,而是使用环回 IP (10.0.2.2) 与本地计算机进行通信。 使用 Xamarin.Essentials DeviceInfo 检测正在运行的操作系统,以使用正确的 URL。

转到 TodoREST 项目,并打开 Constants.cs 文件。 Constants.cs 文件包含以下配置。

using Xamarin.Essentials; using Xamarin.Forms; namespace TodoREST { public static class Constants { // URL of REST service //public static string RestUrl = "https://YOURPROJECT.azurewebsites.net:8081/api/todoitems/{0}"; // URL of REST service (Android does not use localhost) // Use http cleartext for local deployment. Change to https for production public static string RestUrl = DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000/api/todoitems/{0}" : "http://localhost:5000/api/todoitems/{0}"; } }

可以选择性地将 Web 服务部署到 Azure 等云服务并更新 RestUrl。

创建 ASP.NET Core 项目

在 Visual Studio 中创建一个新的 ASP.NET Core Web 应用程序。 选择 Web API 模板。 将项目命名为 TodoAPI。

该应用应响应向端口 5000 发出的所有请求,包括我们移动客户端的明文 HTTP 流量。 更新 Startup.cs,使 UseHttpsRedirection 不在开发中运行:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // For mobile apps, allow http traffic. app.UseHttpsRedirection(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }

注意

直接运行应用,而不是在 IIS Express 后面。 IIS Express 将默认忽略非本地请求。 从命令提示符处运行 dotnet run,或从 Visual Studio 工具栏中的“调试目标”下拉列表中选择应用名称配置文件。

添加一个模型类来表示待办事项。 使用 [Required] 属性标记必需字段:

using System.ComponentModel.DataAnnotations; namespace TodoAPI.Models { public class TodoItem { [Required] public string ID { get; set; } [Required] public string Name { get; set; } [Required] public string Notes { get; set; } public bool Done { get; set; } } }

API 方法需要通过某种方式处理数据。 使用原始 Xamarin 示例所用的 ITodoRepository 接口:

using System.Collections.Generic; using TodoAPI.Models; namespace TodoAPI.Interfaces { public interface ITodoRepository { bool DoesItemExist(string id); IEnumerable All { get; } TodoItem Find(string id); void Insert(TodoItem item); void Update(TodoItem item); void Delete(string id); } }

在此示例中,该实现仅使用一个专用项集合:

using System.Collections.Generic; using System.Linq; using TodoAPI.Interfaces; using TodoAPI.Models; namespace TodoAPI.Services { public class TodoRepository : ITodoRepository { private List _todoList; public TodoRepository() { InitializeData(); } public IEnumerable All { get { return _todoList; } } public bool DoesItemExist(string id) { return _todoList.Any(item => item.ID == id); } public TodoItem Find(string id) { return _todoList.FirstOrDefault(item => item.ID == id); } public void Insert(TodoItem item) { _todoList.Add(item); } public void Update(TodoItem item) { var todoItem = this.Find(item.ID); var index = _todoList.IndexOf(todoItem); _todoList.RemoveAt(index); _todoList.Insert(index, item); } public void Delete(string id) { _todoList.Remove(this.Find(id)); } private void InitializeData() { _todoList = new List(); var todoItem1 = new TodoItem { ID = "6bb8a868-dba1-4f1a-93b7-24ebce87e243", Name = "Learn app development", Notes = "Take Microsoft Learn Courses", Done = true }; var todoItem2 = new TodoItem { ID = "b94afb54-a1cb-4313-8af3-b7511551b33b", Name = "Develop apps", Notes = "Use Visual Studio and Visual Studio for Mac", Done = false }; var todoItem3 = new TodoItem { ID = "ecfa6f80-3671-4911-aabe-63cc442c1ecf", Name = "Publish apps", Notes = "All app stores", Done = false, }; _todoList.Add(todoItem1); _todoList.Add(todoItem2); _todoList.Add(todoItem3); } } }

在 Startup.cs 中配置实现:

public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); services.AddControllers(); } 创建控制器

在项目中添加新控制器 TodoItemsController。 它应该从 ControllerBase 继承。 添加 Route 属性以指示控制器处理针对以 api/todoitems 开头的路径发出的请求。 路由中的 [controller] 标记会被控制器的名称代替(省略 Controller 后缀),这对全局路由特别有用。 详细了解 路由。

控制器需要 ITodoRepository 才能正常运行;通过控制器的构造函数请求该类型的实例。 在运行时,将使用框架对依赖关系注入的支持来提供此实例。

[ApiController] [Route("api/[controller]")] public class TodoItemsController : ControllerBase { private readonly ITodoRepository _todoRepository; public TodoItemsController(ITodoRepository todoRepository) { _todoRepository = todoRepository; }

此 API 支持四个不同的 HTTP 谓词来执行对数据源的 CRUD(创建、读取、更新、删除)操作。 其中最简单的是读取操作,它对应于 HTTP GET 请求。

使用 curl 测试 API

你可以使用各种工具来测试 API 方法。 在本教程中,将使用以下开源命令行工具:

curl:使用各种协议(包括 HTTP 和 HTTPS)传输数据。 curl 在本教程中用于通过 HTTP 方法 GET、POST、PUT 和 DELETE 来调用 API。 jq:本教程中使用的 JSON 处理器,用于格式化 JSON 数据,以便从 API 响应中轻松读取。 安装 curl 和 jq macOS Windows

curl 已在 macOS 中预安装,可直接在 macOS 终端应用程序中使用。 有关安装 curl 的详细信息,请参阅官方 curl 网站。

jq 可以在终端中使用 Homebrew 安装:

使用以下命令安装 Homebrew(如果尚未安装):

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

按照安装程序提供的说明进行操作。

通过以下命令使用 Homebrew 安装 jq:

brew install jq

有关 Homebrew 和 jq 安装的详细信息,请参阅 Homebrew 和 jq。

curl 会随 Windows 10 版本 1802 或更高版本一起安装。 有关安装 curl 的详细信息,请参阅官方 curl 网站。

在 PowerShell 或命令提示符中使用以下命令安装 jq:

winget install jqlang.jq

PowerShell 或命令提示符关闭并重启后,jq 命令将可用。

有关 jq 安装的更多详细信息,请参阅 jq。

读取项目

要请求项列表,可对 List 方法使用 GET 请求。 [HttpGet] 方法的 List 属性指示此操作应仅处理 GET 请求。 此操作的路由是在控制器上指定的路由。 你不一定必须将操作名称用作路由的一部分。 你只需确保每个操作都有唯一的和明确的路由。 路由属性可以分别应用在控制器和方法级别,以此生成特定的路由。

[HttpGet] public IActionResult List() { return Ok(_todoRepository.All); } macOS Windows

在终端中,调用以下 curl 命令:

curl -v -X GET 'http://localhost:5000/api/todoitems/' | jq

注意

Windows PowerShell 5.1 会将 curl 识别为 Invoke-WebRequst 的别名。 若要改用 curl.exe,请键入 & 运算符,然后键入 curl.exe 的完整路径。 通过在命令提示符中键入 where curl 来查找 curl.exe 的完整路径。 例如,如果 curl.exe 的完整路径为 C:\Windows\System32\curl.exe, 那么请使用 & 'C:\Windows\System32\curl.exe' --help,而不是键入命令 curl --help。 PowerShell 7 使用 curl 作为 curl.exe 的命令,因此不需要完整路径。

在 PowerShell 中,调用以下 curl 命令:

curl -v -X GET 'http://localhost:5000/api/todoitems/' | jq

前面的 curl 命令包含以下组成部分:

-v:激活详细模式,以提供有关 HTTP 响应的详细信息,对于 API 测试和故障排除非常有用。 -X GET:指定对请求使用 HTTP GET 方法。 虽然 curl 通常可以推断预期的 HTTP 方法,但此选项可使其更明确。 'http://localhost:5000/api/todoitems/':这是请求的目标 URL。 在此实例中,它是一个 REST API 终结点。 | jq:此片段与 curl 没有直接关系。 管道 | 是一个 shell 运算符,它从自身左侧的命令获取输出,并将其传输给右侧的命令。 jq 是一个命令行 JSON 处理器。 虽然 jq 不是必需的,但它使返回的 JSON 数据更易于读取。

List 方法将返回一个 200 OK 响应代码和所有 Todo 项,并将起序列化为 JSON:

[ { "id": "6bb8a868-dba1-4f1a-93b7-24ebce87e243", "name": "Learn app development", "notes": "Take Microsoft Learn Courses", "done": true }, { "id": "b94afb54-a1cb-4313-8af3-b7511551b33b", "name": "Develop apps", "notes": "Use Visual Studio and Visual Studio for Mac", "done": false }, { "id": "ecfa6f80-3671-4911-aabe-63cc442c1ecf", "name": "Publish apps", "notes": "All app stores", "done": false } ] 创建项目

按照约定,创建新数据项将映射到 HTTP POST 谓词。 Create 方法具有应用于它的 [HttpPost] 属性,并接受 TodoItem 实例。 由于 item 参数在 POST 的正文中传递,因此该参数会指定 [FromBody] 属性。

在该方法中,会检查项的有效性和之前是否存在于数据存储,并且如果没有任何问题,则使用存储库添加。 检查 ModelState.IsValid 将执行 模型验证,应该在每个接受用户输入的 API 方法中执行此步骤。

[HttpPost] public IActionResult Create([FromBody]TodoItem item) { try { if (item == null || !ModelState.IsValid) { return BadRequest(ErrorCode.TodoItemNameAndNotesRequired.ToString()); } bool itemExists = _todoRepository.DoesItemExist(item.ID); if (itemExists) { return StatusCode(StatusCodes.Status409Conflict, ErrorCode.TodoItemIDInUse.ToString()); } _todoRepository.Insert(item); } catch (Exception) { return BadRequest(ErrorCode.CouldNotCreateItem.ToString()); } return Ok(item); }

该示例使用包含传递给移动客户端的错误代码的 enum:

public enum ErrorCode { TodoItemNameAndNotesRequired, TodoItemIDInUse, RecordNotFound, CouldNotCreateItem, CouldNotUpdateItem, CouldNotDeleteItem }

在终端中,使用 POST 谓词调用以下 curl 命令,并在请求正文中以 JSON 格式提供新对象来测试添加新项的表现。

macOS Windows curl -v -X POST 'http://localhost:5000/api/todoitems/' \ --header 'Content-Type: application/json' \ --data '{ "id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243", "name": "A Test Item", "notes": "asdf", "done": false }' | jq curl -v -X POST 'http://localhost:5000/api/todoitems/' ` --header 'Content-Type: application/json' ` --data '{ "id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243", "name": "A Test Item", "notes": "asdf", "done": false }' | jq

前面的 curl 命令包括以下选项:

--header 'Content-Type: application/json':将 Content-Type 标头设置为 application/json,以指示请求正文包含 JSON 数据。 --data '{...}':发送请求正文中指定的数据。

该方法返回在响应中新建的项。

更新项目

修改记录可通过 HTTP PUT 请求完成。 除了此更改之外,Edit 方法几乎与 Create 完全相同。 如果未找到相应记录,Edit 操作将返回 NotFound (404) 响应。

[HttpPut] public IActionResult Edit([FromBody] TodoItem item) { try { if (item == null || !ModelState.IsValid) { return BadRequest(ErrorCode.TodoItemNameAndNotesRequired.ToString()); } var existingItem = _todoRepository.Find(item.ID); if (existingItem == null) { return NotFound(ErrorCode.RecordNotFound.ToString()); } _todoRepository.Update(item); } catch (Exception) { return BadRequest(ErrorCode.CouldNotUpdateItem.ToString()); } return NoContent(); }

若要使用 curl 进行测试,请将谓词更改为 PUT。 在请求正文中指定要更新的对象数据。

macOS Windows curl -v -X PUT 'http://localhost:5000/api/todoitems/' \ --header 'Content-Type: application/json' \ --data '{ "id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243", "name": "A Test Item", "notes": "asdf", "done": true }' | jq curl -v -X PUT 'http://localhost:5000/api/todoitems/' ` --header 'Content-Type: application/json' ` --data '{ "id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243", "name": "A Test Item", "notes": "asdf", "done": true }' | jq

为了与预先存在的 API 保持一致,此方法在成功时返回 NoContent (204) 响应。

删除项

删除记录可以通过向服务发出 DELETE 请求并传递要删除项的 ID 来完成。 与更新一样,请求的项不存在时会收到 NotFound 响应。 否则,成功的请求将返回 NoContent (204) 响应。

[HttpDelete("{id}")] public IActionResult Delete(string id) { try { var item = _todoRepository.Find(id); if (item == null) { return NotFound(ErrorCode.RecordNotFound.ToString()); } _todoRepository.Delete(id); } catch (Exception) { return BadRequest(ErrorCode.CouldNotDeleteItem.ToString()); } return NoContent(); }

请将 HTTP 谓词更改为 DELETE 并在 URL 末尾追加要删除的数据对象的 ID,以使用 curl 进行测试。 请求正文中不需要任何内容。

macOS Windows curl -v -X DELETE 'http://localhost:5000/api/todoitems/6bb8b868-dba1-4f1a-93b7-24ebce87e243' curl -v -X DELETE 'http://localhost:5000/api/todoitems/6bb8b868-dba1-4f1a-93b7-24ebce87e243' 防止过度发布

目前,示例应用公开了整个 TodoItem 对象。 生产应用通常使用模型的子集来限制输入和返回的数据。 这背后有多种原因,但安全性是主要原因。 模型的子集通常称为数据传输对象 (DTO)、输入模型或视图模型。 本文使用的是 DTO。

DTO 可用于:

防止过度发布。 隐藏客户端不应查看的属性。 省略某些属性以减少有效负载大小。 平展包含嵌套对象的对象图。 对客户端而言,平展的对象图可能更方便。

要演示 DTO 方法,请参阅防止过度发布

常见的 Web API 约定

开发应用的后端服务时,需要制定一组一致的约定或策略来处理跨领域问题。 例如,在上面所示的服务中,未找到请求的特定记录时会收到 NotFound 响应,而不是 BadRequest 响应。 同样,对于此服务,传递模型绑定类型的命令始终检查 ModelState.IsValid 并为无效的模型类型返回 BadRequest。

一旦为 Api 指定通用策略,一般可以将其封装在 Filter(筛选器)。 详细了解 如何封装 ASP.NET Core MVC 应用程序中的通用 API 策略。

其他资源 Xamarin.Forms:Web 服务身份验证 Xamarin.Forms:使用 RESTful Web 服务 在 Xamarin 应用中使用 REST Web 服务 使用 ASP.NET Core 创建 Web API


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有