教程:通过 .NET SDK 开发使用 Azure Cosmos DB 的 ASP.NET Core MVC Web 应用程序

适用于: SQL API

本教程介绍如何使用 Azure Cosmos DB 通过 Azure 上托管的 ASP.NET MVC 应用程序存储和访问数据。 在本教程中,请使用 .NET SDK V3。 下图显示将要使用本文中的示例生成的网页:

按本教程(ASP NET Core MVC 分步教程)创建的待办事项列表 MVC Web 应用程序的屏幕截图

如果没有时间完成本教程,可以从 GitHub 下载完整的示例项目。

本教程涉及:

  • 创建 Azure Cosmos 帐户
  • 创建 ASP.NET Core MVC 应用
  • 将应用连接到 Azure Cosmos DB
  • 对数据执行创建、读取、更新和删除 (CRUD) 操作

提示

本教程假定你先前有使用 ASP.NET Core MVC 和 Azure 应用服务的经验。 如果你不熟悉 ASP.NET Core 或必备工具,我们建议从 GitHub 下载完整的示例项目,然后添加所需的 NuGet 包并运行它。 生成项目之后,可以回顾本文以深入了解项目上下文中的代码。

先决条件

在按照本文中的说明操作之前,请确保具备以下资源:

本文中的所有屏幕截图都是在 Microsoft Visual Studio Community 2019 中截取的。 如果你使用其他版本,则屏幕截图和选项可能不与此完全相同。 如果满足先决条件,解决方案应可正常运行。

步骤 1:创建 Azure Cosmos 帐户

让我们首先创建一个 Azure Cosmos 帐户。 如果你已有一个 Azure Cosmos DB SQL API 帐户,或者使用的是 Azure Cosmos DB 仿真程序,请跳到步骤 2:创建新的 ASP.NET MVC 应用程序

  1. 在 Azure 门户菜单或主页中,选择“创建资源” 。

  2. 在“新建”页面中搜索“Azure Cosmos DB”,然后选择它。

  3. 在“Azure Cosmos DB”页上,选择“创建”。

  4. 在“创建 Azure Cosmos DB 帐户”页中,输入新 Azure Cosmos 帐户的基本设置。

    设置 说明
    订阅 订阅名称 选择要用于此 Azure Cosmos 帐户的 Azure 订阅。
    资源组 资源组名称 选择一个资源组,或者选择“新建”,然后输入新资源组的唯一名称。
    帐户名 唯一的名称 输入标识此 Azure Cosmos 帐户的名称。 由于 documents.azure.cn 将追加到所提供的名称以创建 URI,因此,请使用唯一的名称。

    名称只能包含小写字母、数字和连字符 (-)。 它的长度必须介于 3-44 个字符之间。
    API 要创建的帐户的类型 选择“Core (SQL)”,以便使用 SQL 语法创建文档数据库并进行查询。

    API 确定要创建的帐户的类型。 Azure Cosmos DB 提供五种 API:适用于文档数据的 Core (SQL) 和 MongoDB、适用于图形数据的 Gremlin、Azure 表和 Cassandra。 目前,你必须为每种 API 创建单独的帐户。

    详细了解 SQL API
    位置 离用户最近的区域 选择用于托管 Azure Cosmos DB 帐户的地理位置。 使用离用户最近的位置,使他们能够以最快的速度访问数据。
    容量模式 预配吞吐量或无服务器 选择“预配吞吐量”以在预配吞吐量模式下创建帐户。 选择“无服务器”以在无服务器模式下创建帐户。
    应用免费层折扣 “应用”或“不应用” 使用 Azure Cosmos DB 免费层,你将在帐户中获得每秒前 1000 RU 的免费吞吐量和 25 GB 的免费存储。 了解免费层的详细信息。

    备注

    每个 Azure 订阅最多可以有一个免费层 Azure Cosmos DB 帐户,并且你必须在创建帐户时选择加入使用。 如果看不到用于应用免费层折扣的选项,这意味着订阅中的另一个帐户已启用免费层。

    Azure Cosmos DB 的“新建帐户”页面

  5. 在“全局分发”选项卡中,配置以下详细信息。 对于本快速入门,可以保留默认值:

    设置 说明
    异地冗余 禁用 通过将你的区域与某个配对区域进行配对来启用或禁用帐户的多区域分发。 稍后可以将更多区域添加到帐户。
    多区域写入 禁用 借助多区域写入功能,可以利用全中国的数据库和容器的预配吞吐量。

    备注

    如果选择“无服务器”作为“容量模式”,则以下选项不可用 :

    • 应用免费层折扣
    • 异地冗余
    • 多区域写入
  6. (可选)可以在以下选项卡中配置其他详细信息:

    • 网络 - 配置 来自虚拟网络的访问

    • 备份策略 - 配置 定期备份策略。

    • 加密 - 使用服务管理的密钥或 客户管理的密钥

    • 标记 - 标记是名称/值对,通过将相同的标记应用到多个资源和资源组,可以对资源进行分类并查看合并的账单。

  7. 选择“查看 + 创建”。

  8. 检查帐户设置,然后选择“创建”。 创建帐户需要几分钟时间。 等待门户页显示“你的部署已完成”消息。

    Azure 门户“通知”窗格

  9. 选择“转到资源”,转到 Azure Cosmos DB 帐户页。

    Azure Cosmos DB 帐户页面

转到 Azure Cosmos DB 帐户页,并选择“密钥”。 复制要在下一步创建的 Web 应用程序中使用的值。

Azure 门户的 Azure Cosmos DB 帐户页上突出显示密钥按钮的屏幕截图

在下一部分,将新建一个 ASP.NET Core MVC 应用程序。

步骤 2:新建 ASP.NET Core MVC 应用程序

  1. 打开 Visual Studio 并选择“创建新项目”。

  2. 在“创建新项目”中,找到并选择适用于 C# 的“ASP.NET Core Web 应用程序”。 选择“下一步”继续。

    新建 ASP.NET Core Web 应用程序项目

  3. 在“配置新项目”中,将项目命名为 todo,然后选择“创建”。

  4. 在“创建新的 ASP.NET Core Web 应用程序”中,选择“Web 应用程序(模型-视图-控制器)”。 选择“创建”继续操作。

    Visual Studio 将创建一个空的 MVC 应用程序。

  5. 选择“调试” > “开始调试”或按 F5,在本地运行 ASP.NET 应用程序。

步骤 3:向项目添加 Azure Cosmos DB NuGet 包

有了此解决方案所需的大多数 ASP.NET Core MVC 框架代码以后,即可添加连接到 Azure Cosmos DB 所需的 NuGet 包。

  1. 在“解决方案资源管理器”中,右键单击项目并选择“管理 NuGet 包”。

  2. 在“NuGet 包管理器”中,搜索并选择“Microsoft.Azure.Cosmos”。 选择“安装”。

    安装 NuGet 包

    Visual Studio 会下载并安装 Azure Cosmos DB 包及其依赖项。

    你也可以使用“包管理器控制台”来安装 NuGet 包。 为此,请选择“工具” > “NuGet 包管理器” > “包管理器控制台”。 在提示符处键入以下命令:

    Install-Package Microsoft.Azure.Cosmos
    

步骤 4:设置 ASP.NET Core MVC 应用程序

现在,让我们向此 MVC 应用程序添加模型、视图和控制器。

添加模型

  1. 在“解决方案资源管理器”中,右键单击“模型”文件夹并选择“添加” > “类”。

  2. 在“添加新项”中,将新类命名为 Item.cs,然后选择“添加”。

  3. Item.cs 类的内容替换为以下代码:

    namespace todo.Models
    {
       using Newtonsoft.Json;
    
       public class Item
       {
           [JsonProperty(PropertyName = "id")]
           public string Id { get; set; }
    
           [JsonProperty(PropertyName = "name")]
           public string Name { get; set; }
    
           [JsonProperty(PropertyName = "description")]
           public string Description { get; set; }
    
           [JsonProperty(PropertyName = "isComplete")]
           public bool Completed { get; set; }
       }
    }
    

Azure Cosmos DB 使用 JSON 来移动和存储数据。 可以使用 JsonProperty 属性来控制 JSON 序列化和反序列化对象的方式。 Item 类演示 JsonProperty 属性。 此代码控制进入 JSON 的属性名称的格式。 它还将 .NET 属性重命名为 Completed

添加视图

接下来,让我们添加以下视图。

  • 创建项视图
  • 删除项视图
  • 用于获取项详细信息的视图
  • 编辑项视图
  • 用于列出所有项的视图

创建项视图

  1. 在“解决方案资源管理器”中,右键单击“视图”文件夹并选择“添加” > “新建文件夹”。 将文件夹命名为“项”。

  2. 右键单击空的“项”文件夹,并选择“添加” > “视图”。

  3. 在“添加 MVC 视图”中进行以下更改:

    • 在“视图名称”中,输入“创建”。
    • 在“模板”中选择“创建”。
    • 在“模型类”中,选择“项(todo.Models)”。
    • 选择“使用布局页”并输入 ~/Views/Shared/_Layout.cshtml
    • 选择 添加

    显示“添加 MVC 视图”对话框的屏幕截图

  4. 接下来,选择“添加”并让 Visual Studio 创建新的模板视图。 将生成的文件中的代码替换为以下内容:

    @model todo.Models.Item
    
    @{
       ViewBag.Title = "Create";
       Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>Create a new To-Do Item</h2>
    
    @using (Html.BeginForm()) 
    {
       @Html.AntiForgeryToken()
    
       <div class="form-horizontal">
           <hr />
           @Html.ValidationSummary(true, "", new { @class = "text-danger" })
           <div class="form-group">
               @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
               <div class="col-md-10">
                   @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                   @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
               </div>
           </div>
    
           <div class="form-group">
               @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
               <div class="col-md-10">
                   @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
                   @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
               </div>
           </div>
    
           <div class="form-group">
               @Html.LabelFor(model => model.Completed, htmlAttributes: new { @class = "control-label col-md-2" })
               <div class="col-md-10">
                   <div class="checkbox">
                       @Html.EditorFor(model => model.Completed)
                       @Html.ValidationMessageFor(model => model.Completed, "", new { @class = "text-danger" })
                   </div>
               </div>
           </div>
    
           <div class="form-group">
               <div class="col-md-offset-2 col-md-10">
                   <input type="submit" value="Create" class="btn btn-default" />
               </div>
           </div>
       </div>
    }
    
    <div>
       @Html.ActionLink("Back to List", "Index")
    </div>
    <script src="~/bundles/jqueryval"></script>
    

删除项视图

  1. 在“解决方案资源管理器”中,再次右键单击“项”文件夹,并选择“添加” > “视图”。

  2. 在“添加 MVC 视图”中进行以下更改:

    • 在“视图名称”框中键入“删除”。
    • 在“模板”框中,选择“删除” 。
    • 在“模型类”框中,选择“项(todo.Models)”。
    • 选择“使用布局页”并输入 ~/Views/Shared/_Layout.cshtml
    • 选择 添加
  3. 接下来,选择“添加”并让 Visual Studio 创建新的模板视图。 将生成的文件中的代码替换为以下内容:

    @model todo.Models.Item
    
    @{
       ViewBag.Title = "Delete";
       Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>Delete a To-Do Item</h2>
    
    <h3>Are you sure you want to delete this?</h3>
    <div>
       <hr />
       <dl class="dl-horizontal">
           <dt>
               @Html.DisplayNameFor(model => model.Name)
           </dt>
    
           <dd>
               @Html.DisplayFor(model => model.Name)
           </dd>
    
           <dt>
               @Html.DisplayNameFor(model => model.Description)
           </dt>
    
           <dd>
               @Html.DisplayFor(model => model.Description)
           </dd>
    
           <dt>
               @Html.DisplayNameFor(model => model.Completed)
           </dt>
    
           <dd>
               @Html.DisplayFor(model => model.Completed)
           </dd>
       </dl>
    
       @using (Html.BeginForm()) {
           @Html.AntiForgeryToken()
    
           <div class="form-actions no-color">
               <input type="submit" value="Delete" class="btn btn-default" /> |
               @Html.ActionLink("Back to List", "Index")
           </div>
       }
    </div>
    

添加用于获取项详细信息的视图

  1. 在“解决方案资源管理器”中,再次右键单击“项”文件夹,并选择“添加” > “视图”。

  2. 在“添加 MVC 视图”中提供以下值:

    • 在“视图名称”中,输入“详细信息”。
    • 在“模板”中选择“详细信息” 。
    • 在“模型类”中,选择“项(todo.Models)”。
    • 选择“使用布局页”并输入 ~/Views/Shared/_Layout.cshtml
  3. 接下来,选择“添加”并让 Visual Studio 创建新的模板视图。 将生成的文件中的代码替换为以下内容:

    @model todo.Models.Item
    
    <h2>View To-Do Item Details</h2>
    
    <div>
       <h4>Item</h4>
       <hr />
       <dl class="dl-horizontal">
           <dt>
               @Html.DisplayNameFor(model => model.Name)
           </dt>
    
           <dd>
               @Html.DisplayFor(model => model.Name)
           </dd>
    
           <dt>
               @Html.DisplayNameFor(model => model.Description)
           </dt>
    
           <dd>
               @Html.DisplayFor(model => model.Description)
           </dd>
    
           <dt>
               @Html.DisplayNameFor(model => model.Completed)
           </dt>
    
           <dd>
               @Html.DisplayFor(model => model.Completed)
           </dd>
    
       </dl>
    </div>
    <p>
       @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
       @Html.ActionLink("Back to List", "Index")
    </p>
    

添加“编辑项”视图

  1. 在“解决方案资源管理器”中,再次右键单击“项”文件夹,并选择“添加” > “视图”。

  2. 在“添加 MVC 视图”中进行以下更改:

    • 在“视图名称”框中,键入“编辑”。
    • 在“模板”框中,选择“编辑”。
    • 在“模型类”框中,选择“项(todo.Models)”。
    • 选择“使用布局页”并输入 ~/Views/Shared/_Layout.cshtml
    • 选择 添加
  3. 接下来,选择“添加”并让 Visual Studio 创建新的模板视图。 将生成的文件中的代码替换为以下内容:

    @model todo.Models.Item
    
    <h2>Edit a To-Do Item</h2>
    
    @using (Html.BeginForm())
    {
       @Html.AntiForgeryToken()
    
       <div class="form-horizontal">
           <h4>Item</h4>
           <hr />
           @Html.ValidationSummary(true, "", new { @class = "text-danger" })
           @Html.HiddenFor(model => model.Id)
    
           <div class="form-group">
               @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
               <div class="col-md-10">
                   @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                   @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
               </div>
           </div>
    
           <div class="form-group">
               @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
               <div class="col-md-10">
                   @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
                   @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
               </div>
           </div>
    
           <div class="form-group">
               @Html.LabelFor(model => model.Completed, htmlAttributes: new { @class = "control-label col-md-2" })
               <div class="col-md-10">
                   <div class="checkbox">
                       @Html.EditorFor(model => model.Completed)
                       @Html.ValidationMessageFor(model => model.Completed, "", new { @class = "text-danger" })
                   </div>
               </div>
           </div>
    
           <div class="form-group">
               <div class="col-md-offset-2 col-md-10">
                   <input type="submit" value="Save" class="btn btn-default" />
               </div>
           </div>
       </div>
    }
    
    <div>
       @Html.ActionLink("Back to List", "Index")
    </div>
    
    <script src="~/bundles/jqueryval"></script>
    

添加用于列出所有项的视图

最后,通过以下步骤添加一个用于获取所有项的视图:

  1. 在“解决方案资源管理器”中,再次右键单击“项”文件夹,并选择“添加” > “视图”。

  2. 在“添加 MVC 视图”中进行以下更改:

    • 在“视图名称”框中,键入“索引”。
    • 在“模板”框中,选择“列表”。
    • 在“模型类”框中,选择“项(todo.Models)”。
    • 选择“使用布局页”并输入 ~/Views/Shared/_Layout.cshtml
    • 选择 添加
  3. 接下来,选择“添加”并让 Visual Studio 创建新的模板视图。 将生成的文件中的代码替换为以下内容:

    @model IEnumerable<todo.Models.Item>
    
    @{
       ViewBag.Title = "List of To-Do Items";
       Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>List of To-Do Items</h2>
    
    <table class="table">
       <tr>
           <th>
               @Html.DisplayNameFor(model => model.Name)
           </th>
           <th>
               @Html.DisplayNameFor(model => model.Description)
           </th>
           <th>
               @Html.DisplayNameFor(model => model.Completed)
           </th>
           <th></th>
       </tr>
    
    @foreach (var item in Model) {
       <tr>
           <td>
               @Html.DisplayFor(modelItem => item.Name)
           </td>
           <td>
               @Html.DisplayFor(modelItem => item.Description)
           </td>
           <td>
               @Html.DisplayFor(modelItem => item.Completed)
           </td>
           <td>
               @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
               @Html.ActionLink("Details", "Details", new { id=item.Id }) |
               @Html.ActionLink("Delete", "Delete", new { id=item.Id })
           </td>
       </tr>
    }
    
    </table>
    
    <p>
       @Html.ActionLink("Create New", "Create")
    </p>
    

完成这些步骤后,请在 Visual Studio 中关闭所有 cshtml 文档。

声明并初始化服务

首先我们添加一个类,其中包含用于连接和使用 Azure Cosmos DB 的逻辑。 在本教程中,我们会将该逻辑封装到名为 CosmosDBService 的类和名为 ICosmosDBService 的接口中。 此服务执行 CRUD 操作。 此外,它还执行读取源操作,例如列出不完整的项以及创建、编辑和删除项。

  1. 在“解决方案资源管理器”中,右键单击项目并选择“添加” > “新建文件夹”。 将文件夹命名为“服务”。

  2. 右键单击“服务”文件夹,并选择“添加” > “类”。 将新类命名为 CosmosDBService,然后选择“添加”。

  3. CosmosDBService.cs 的内容替换为以下代码:

    namespace todo
    {
       using System.Collections.Generic;
       using System.Linq;
       using System.Threading.Tasks;
       using todo.Models;
       using Microsoft.Azure.Cosmos;
       using Microsoft.Azure.Cosmos.Fluent;
       using Microsoft.Extensions.Configuration;
    
       public class CosmosDbService : ICosmosDbService
       {
           private Container _container;
    
           public CosmosDbService(
               CosmosClient dbClient,
               string databaseName,
               string containerName)
           {
               this._container = dbClient.GetContainer(databaseName, containerName);
           }
    
           public async Task AddItemAsync(Item item)
           {
               await this._container.CreateItemAsync<Item>(item, new PartitionKey(item.Id));
           }
    
           public async Task DeleteItemAsync(string id)
           {
               await this._container.DeleteItemAsync<Item>(id, new PartitionKey(id));
           }
    
           public async Task<Item> GetItemAsync(string id)
           {
               try
               {
                   ItemResponse<Item> response = await this._container.ReadItemAsync<Item>(id, new PartitionKey(id));
                   return response.Resource;
               }
               catch(CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
               { 
                   return null;
               }
    
           }
    
           public async Task<IEnumerable<Item>> GetItemsAsync(string queryString)
           {
               var query = this._container.GetItemQueryIterator<Item>(new QueryDefinition(queryString));
               List<Item> results = new List<Item>();
               while (query.HasMoreResults)
               {
                   var response = await query.ReadNextAsync();
    
                   results.AddRange(response.ToList());
               }
    
               return results;
           }
    
           public async Task UpdateItemAsync(string id, Item item)
           {
               await this._container.UpsertItemAsync<Item>(item, new PartitionKey(id));
           }
       }
    }
    
  4. 右键单击“服务”文件夹,并选择“添加” > “类”。 将新类命名为“ICosmosDBService”,并选择“添加”。

  5. 将以下代码添加到 ICosmosDBService 类:

    namespace todo
    {
       using System.Collections.Generic;
       using System.Threading.Tasks;
       using todo.Models;
    
       public interface ICosmosDbService
       {
           Task<IEnumerable<Item>> GetItemsAsync(string query);
           Task<Item> GetItemAsync(string id);
           Task AddItemAsync(Item item);
           Task UpdateItemAsync(string id, Item item);
           Task DeleteItemAsync(string id);
       }
    }
    
  6. 在解决方案中打开 Startup.cs 文件,并添加方法 InitializeCosmosClientInstanceAsync,该方法将读取配置并初始化客户端。

    /// <summary>
    /// Creates a Cosmos DB database and a container with the specified partition key. 
    /// </summary>
    /// <returns></returns>
    private static async Task<CosmosDbService> InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
    {
       string databaseName = configurationSection.GetSection("DatabaseName").Value;
       string containerName = configurationSection.GetSection("ContainerName").Value;
       string account = configurationSection.GetSection("Account").Value;
       string key = configurationSection.GetSection("Key").Value;
       Microsoft.Azure.Cosmos.CosmosClient client = new Microsoft.Azure.Cosmos.CosmosClient(account, key);
       CosmosDbService cosmosDbService = new CosmosDbService(client, databaseName, containerName);
       Microsoft.Azure.Cosmos.DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
       await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
    
       return cosmosDbService;
    }
    
    
  7. 在同一文件中,将 ConfigureServices 方法替换为:

    public void ConfigureServices(IServiceCollection services)
    {
       services.AddControllersWithViews();
       services.AddSingleton<ICosmosDbService>(InitializeCosmosClientInstanceAsync(Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult());
    }
    
    

    此步骤中的代码会根据配置,将客户端初始化为要通过 ASP.NET Core 中的依赖项注入功能注入的单一实例。

    通过在同一文件的 Configure 方法中编辑路由,确保将默认 MVC 控制器更改为 Item

    app.UseEndpoints(endpoints =>
          {
                endpoints.MapControllerRoute(
                   name: "default",
                   pattern: "{controller=Item}/{action=Index}/{id?}");
          });
    
  8. 在项目的 appsettings.json 文件中定义配置,如以下代码片段所示:

    {
     "Logging": {
       "LogLevel": {
         "Default": "Warning"
       }
     },
     "AllowedHosts": "*",
     "CosmosDb": {
       "Account": "<Endpoint URI of your Azure Cosmos account>",
       "Key": "<PRIMARY KEY of your Azure Cosmos account>",
       "DatabaseName": "Tasks",
       "ContainerName": "Item"
     }
    }
    

添加控制器

  1. 在“解决方案资源管理器”中,右键单击“控制器”文件夹,并选择“添加” > “控制器”。

  2. 在“添加基架”中,依次选择“MVC 控制器 - 空”、“添加”。

    在“添加基架”中选择“MVC 控制器 - 空”

  3. 将新控制器命名为 ItemController

  4. ItemController.cs 的内容替换为以下代码:

    namespace todo.Controllers
    {
       using System;
       using System.Threading.Tasks;
       using Microsoft.AspNetCore.Mvc;
       using todo.Models;
    
       public class ItemController : Controller
       {
           private readonly ICosmosDbService _cosmosDbService;
           public ItemController(ICosmosDbService cosmosDbService)
           {
               _cosmosDbService = cosmosDbService;
           }
    
           [ActionName("Index")]
           public async Task<IActionResult> Index()
           {
               return View(await _cosmosDbService.GetItemsAsync("SELECT * FROM c"));
           }
    
           [ActionName("Create")]
           public IActionResult Create()
           {
               return View();
           }
    
           [HttpPost]
           [ActionName("Create")]
           [ValidateAntiForgeryToken]
           public async Task<ActionResult> CreateAsync([Bind("Id,Name,Description,Completed")] Item item)
           {
               if (ModelState.IsValid)
               {
                   item.Id = Guid.NewGuid().ToString();
                   await _cosmosDbService.AddItemAsync(item);
                   return RedirectToAction("Index");
               }
    
               return View(item);
           }
    
           [HttpPost]
           [ActionName("Edit")]
           [ValidateAntiForgeryToken]
           public async Task<ActionResult> EditAsync([Bind("Id,Name,Description,Completed")] Item item)
           {
               if (ModelState.IsValid)
               {
                   await _cosmosDbService.UpdateItemAsync(item.Id, item);
                   return RedirectToAction("Index");
               }
    
               return View(item);
           }
    
           [ActionName("Edit")]
           public async Task<ActionResult> EditAsync(string id)
           {
               if (id == null)
               {
                   return BadRequest();
               }
    
               Item item = await _cosmosDbService.GetItemAsync(id);
               if (item == null)
               {
                   return NotFound();
               }
    
               return View(item);
           }
    
           [ActionName("Delete")]
           public async Task<ActionResult> DeleteAsync(string id)
           {
               if (id == null)
               {
                   return BadRequest();
               }
    
               Item item = await _cosmosDbService.GetItemAsync(id);
               if (item == null)
               {
                   return NotFound();
               }
    
               return View(item);
           }
    
           [HttpPost]
           [ActionName("Delete")]
           [ValidateAntiForgeryToken]
           public async Task<ActionResult> DeleteConfirmedAsync([Bind("Id")] string id)
           {
               await _cosmosDbService.DeleteItemAsync(id);
               return RedirectToAction("Index");
           }
    
           [ActionName("Details")]
           public async Task<ActionResult> DetailsAsync(string id)
           {
               return View(await _cosmosDbService.GetItemAsync(id));
           }
       }
    }
    

此处使用的 ValidateAntiForgeryToken 属性可帮助此应用程序防止跨站点请求伪造攻击。 你的视图应该也可以使用此防伪令牌。 有关详细信息和示例,请参阅在 ASP.NET MVC 应用程序中防止跨站点请求伪造 (CSRF) 攻击GitHub 上提供的源代码已有完整实现。

我们还会在方法参数中使用 Bind 属性,帮助防范过度提交攻击。 有关详细信息,请参阅教程:使用 ASP.NET MVC 中的实体框架实现 CRUD 功能

步骤 5:在本地运行应用程序

若要在本地计算机中测试应用程序,请使用以下步骤:

  1. 在 Visual Studio 中按 F5 即可在调试模式下构建应用程序。 这样应该可以构建应用程序,并启动包含先前看到的空白网格页面的浏览器:

    按本教程创建的待办事项列表 Web 应用程序的屏幕截图

    如果应用程序改为打开到主页,请将 /Item 追加到 url。

  2. 选择“新建”链接,并在“名称”和“说明”字段中添加值。 将“已完成”复选框保留未选中状态。 如果选中此复选框,应用会添加处于已完成状态的新项。 该项不再会显示在初始列表中。

  3. 选择“创建”。 应用会将你返回到“索引”视图,项将显示在列表中。 可以在 To-Do 列表中额外添加几个项。

    “索引”视图的屏幕截图

  4. 在列表中“项”的旁边选择“编辑”。 应用将会打开“编辑”视图,可在其中更新对象的任何属性,包括“已完成”标志。 如果你依次选择“已完成”、“保存”,则应用会在列表中显示处于已完成状态的“项”。

    勾选了“已完成”框的“索引”视图屏幕截图

  5. 使用 Azure 门户或 Azure Cosmos DB 仿真器的数据资源管理器来验证 Azure Cosmos DB 服务中数据的状态。

  6. 测试应用后,按 Ctrl+F5 停止调试应用。 可以开始部署了!

步骤 6:部署应用程序

现在,已经拥有了可以使用 Azure Cosmos DB 正常工作的完整应用程序,接下来我们要将此 Web 应用部署到 Azure 应用服务。

  1. 若要发布此应用程序,请右键单击“解决方案资源管理器”中的项目并选择“发布”。

  2. 在“选取发布目标”中选择“应用服务”。

  3. 若要使用现有的应用服务配置文件,请依次选择“选择现有项”、“发布”。

  4. 在“应用服务”中选择“订阅”。 使用“视图”筛选器按资源组或资源类型进行筛选。

  5. 找到你的配置文件,然后选择“确定”。 接下来搜索必需的 Azure 应用服务,然后选择“确定”。

    Visual Studio 中的“应用服务”对话框

另一个选项是创建新的配置文件:

  1. 与在前面的过程中一样,在“解决方案资源管理器”右键单击该项目并选择“发布”。

  2. 在“选取发布目标”中选择“应用服务”。

  3. 在“选取发布目标”中,依次选择“新建”、“发布”。

  4. 在“应用服务”中,输入 Web 应用名称以及相应的订阅、资源组和托管计划,然后选择“创建”。

    Visual Studio 中的“创建应用服务”对话框

在几秒钟内,Visual Studio 会发布 Web 应用程序并启动浏览器,方便你查看在 Azure 中运行的项目!

后续步骤

本教程介绍了如何生成 ASP.NET Core MVC Web 应用程序。 该应用程序可以访问存储在 Azure Cosmos DB 中的数据。 接下来,可以继续学习以下资源: