直接寫入儲存體Write directly to storage

適用于: SDK v4APPLIES TO: SDK v4

您可以將資料直接讀取及寫入至儲存體物件,無需使用中介軟體或內容物件。You can read and write directly to your storage object without using middleware or context object. 這種方式適用於 Bot 使用者用來保留交談的資料,或來自 Bot 交談流程以外來源的資料。This can be appropriate for data your bot uses to preserve a conversation, or data that comes from a source outside your bot's conversation flow. 在此資料儲存體模型中,資料會直接從儲存體讀取,而非使用狀態管理員。In this data storage model, data is read in directly from storage instead of using a state manager. 本文中的程式碼範例會示範如何使用 記憶體Cosmos DBazure blobazure blob 文字記錄 儲存體,將資料讀取和寫入至儲存體。The code examples in this article show you how to read and write data to storage using memory, Cosmos DB, Azure Blob, and Azure Blob transcript storage.

PrerequisitesPrerequisites

注意

VSIX封裝包含 .net core 2.1 和 .net core 3.1 版本的 c # 範本。The VSIX package includes both .NET Core 2.1 and .NET Core 3.1 versions of the C# templates. 在 Visual Studio 2019 中建立新的 Bot 時,您應該使用 .NET Core 3.1 範本。When creating new bots in Visual Studio 2019, you should use the .NET Core 3.1 templates. 目前的 Bot 範例會使用 .NET Core 3.1 範本。The current bot samples use .NET Core 3.1 templates. 您可以在 BotBuilder-Samples 存放庫的 4.7-archive 分支中,找到使用 .NET Core 2.1 範本的範例。You can find the samples that use .NET Core 2.1 templates in the 4.7-archive branch of the BotBuilder-Samples repository. 如需將 .NET Core 3.1 bot 部署至 Azure 的詳細資訊,請參閱如何將 您的 bot 部署至 azureFor information about deploying .NET Core 3.1 bots to Azure, see how to deploy your bot to Azure.

關於此範例About this sample

本文中的範例程式碼是以基本 Echo Bot 的結構開頭,然後藉由新增額外的程式碼 (下面提供) 來擴充該 Bot 的功能。The sample code in this article begins with the structure of a basic echo bot, then extends that bot's functionality by adding additional code (provided below). 此擴充程式碼會建立一份清單,以保留其收到的使用者輸入。This extended code creates a list to preserve user inputs as they are received. 在每個回合中,系統會將完整的使用者輸入清單回應給使用者。Each turn, the full list of user inputs is echoed back to the user. 在該回合結束時,包含此輸入清單的資料結構會接著儲存到儲存體。The data structure containing this list of inputs is then saved to storage at the end of that turn. 系統會在此範例程式碼中加入其他功能,以探索各種類型的儲存體。Various types of storage are explored as additional functionality is added to this sample code.

記憶體儲存體Memory storage

Bot Framework SDK 可讓您使用「記憶體內部儲存體」來儲存使用者輸入。The Bot Framework SDK allows you to store user inputs using in-memory storage. 記憶體儲存體僅供測試用途,而不適用於生產環境。Memory storage is used for testing purposes only and is not intended for production use. 記憶體內部儲存體是變動且暫時的,因為每次 Bot 重新啟動時,就會清除資料。In-memory storage is volatile and temporary since the data is cleared each time the bot is restarted. 生產 Bot 最適合使用永續性儲存體類型 (例如資料庫儲存體)。Persistent storage types, such as database storage, are best for production bots. 務必先將儲存體設定為 [Cosmos DB]、[Blob 儲存體]或 Azure 資料表儲存體,再發佈您的 Bot。Be sure to set storage to Cosmos DB, Blob Storage, or Azure Table storage before publishing your bot.

建置基本 BotBuild a basic bot

本主題的其餘部分是以 Echo Bot 為基礎。The rest of this topic builds off of an Echo bot. 依照建置 C# EchoBotJS EchoBotPython EchoBot 的快速入門指示,可以在本機建置 Echo Bot 範例程式碼。The Echo bot sample code can be locally built by following the Quickstart instructions for building either a C# EchoBot, JS EchoBot or Python EchoBot.

EchoBot.csEchoBot.cs

using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

// Represents a bot saves and echoes back user input.
public class EchoBot : ActivityHandler
{
   // Create local Memory Storage.
   private static readonly MemoryStorage _myStorage = new MemoryStorage();

   // Create cancellation token (used by Async Write operation).
   public CancellationToken cancellationToken { get; private set; }

   // Class for storing a log of utterances (text of messages) as a list.
   public class UtteranceLog : IStoreItem
   {
      // A list of things that users have said to the bot
      public List<string> UtteranceList { get; } = new List<string>();

      // The number of conversational turns that have occurred
      public int TurnNumber { get; set; } = 0;

      // Create concurrency control where this is used.
      public string ETag { get; set; } = "*";
   }

   // Echo back user input.
   protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
   {
      // preserve user input.
      var utterance = turnContext.Activity.Text;

      // Make empty local log-items list.
      UtteranceLog logItems = null;

      // See if there are previous messages saved in storage.
      try
      {
         string[] utteranceList = { "UtteranceLog" };
         logItems = _myStorage.ReadAsync<UtteranceLog>(utteranceList).Result?.FirstOrDefault().Value;
      }
      catch
      {
         // Inform the user an error occurred.
         await turnContext.SendActivityAsync("Sorry, something went wrong reading your stored messages!");
      }

      // If no stored messages were found, create and store a new entry.
      if (logItems is null)
      {
         // Add the current utterance to a new object.
         logItems = new UtteranceLog();
         logItems.UtteranceList.Add(utterance);

         // Set initial turn counter to 1.
         logItems.TurnNumber++;

         // Show user new user message.
         await turnContext.SendActivityAsync($"{logItems.TurnNumber}: The list is now: {string.Join(", ", logItems.UtteranceList)}");

         // Create dictionary object to hold received user messages.
         var changes = new Dictionary<string, object>();
         {
            changes.Add("UtteranceLog", logItems);
         }
         try
         {
            // Save the user message to your Storage.
            await _myStorage.WriteAsync(changes, cancellationToken);
         }
         catch
         {
            // Inform the user an error occurred.
            await turnContext.SendActivityAsync("Sorry, something went wrong storing your message!");
         }
      }
      // Else, our storage already contained saved user messages, add new one to the list.
      else
      {
         // add new message to list of messages to display.
         logItems.UtteranceList.Add(utterance);
         // increment turn counter.
         logItems.TurnNumber++;

         // show user new list of saved messages.
         await turnContext.SendActivityAsync($"{logItems.TurnNumber}: The list is now: {string.Join(", ", logItems.UtteranceList)}");

         // Create Dictionary object to hold new list of messages.
         var changes = new Dictionary<string, object>();
         {
            changes.Add("UtteranceLog", logItems);
         };

         try
         {
            // Save new list to your Storage.
            await _myStorage.WriteAsync(changes,cancellationToken);
         }
         catch
         {
            // Inform the user an error occurred.
            await turnContext.SendActivityAsync("Sorry, something went wrong storing your message!");
         }
      }
      ...  // OnMessageActivityAsync( )
   }
}

啟動 BotStart your bot

在本機執行您的 Bot。Run your bot locally.

啟動模擬器並連線至您的 BotStart the Emulator and connect your bot

接下來安裝 Bot Framework 模擬器 、啟動模擬器,然後連線到您在模擬器中的 Bot:Install the Bot Framework Emulator Next, start the Emulator and then connect to your bot in the Emulator:

  1. 在模擬器的 [歡迎使用] 索引標籤中,按一下 [ 建立新的 bot 設定] 連結。Click the Create new bot configuration link in the Emulator "Welcome" tab.
  2. 以您啟動 Bot 時顯示在網頁上的資訊,填妥欄位以連線到 Bot。Fill in fields to connect to your bot, given the information on the webpage displayed when you started your bot.

與您的 Bot 互動Interact with your bot

將訊息傳送給 Bot。Send a message to your bot. Bot 會列出所收到的訊息。The bot will list the messages it has received.

模擬器測試儲存體 Bot

使用 Cosmos DBUsing Cosmos DB

重要

「Cosmos DB 儲存體」類別已遭取代。The Cosmos DB storage class has been deprecated. 原本以 CosmosDbStorage 建立的容器沒有設定分割區索引鍵,而且會提供 _ partitionKey 的預設分割區索引鍵 / __。Containers originally created with CosmosDbStorage had no partition key set, and were given the default partition key of _/partitionKey.

使用 Cosmos DB 儲存體 建立的容器可以搭配 Cosmos DB 分割的儲存體 使用。Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. 如需詳細資訊,請參閱 Azure Cosmos DB 中的資料分割Read Partitioning in Azure Cosmos DB for more information.

另請注意,與舊版 Cosmos DB 儲存體不同的是,Cosmos DB 分割的儲存體不會自動在您的 Cosmos DB 帳戶內建立資料庫。Also note that, unlike the legacy Cosmos DB storage, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account. 您需要 手動建立新的資料庫,但略過手動建立容器,因為 CosmosDbPartitionedStorage 會為您建立容器。You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

既然您已使用記憶體儲存體,我們會將程式碼更新為使用 Azure Cosmos DB。Now that you've used memory storage, we'll update the code to use Azure Cosmos DB. Cosmos DB 是 Microsoft 全球發行的多模型資料庫。Cosmos DB is Microsoft's globally distributed, multi-model database. Azure Cosmos DB 可讓您有彈性且獨立地跨任意數目的 Azure 地理區域調整輸送量和儲存體。Azure Cosmos DB enables you to elastically and independently scale throughput and storage across any number of Azure's geographic regions. 它利用完整的服務等級協定 (SLA) 提供了輸送量、延遲、可用性和一致性的保證。It offers throughput, latency, availability, and consistency guarantees with comprehensive service level agreements (SLAs).

設定 Cosmos DB 資源Set up a Cosmos DB resource

若要在 Bot 中使用 Cosmos DB,您需要先建立資料庫資源,然後再進入程式碼。To use Cosmos DB in your bot, you'll need to create a database resource before getting into the code. 如需建立 Cosmos DB 資料庫和應用程式的深入說明,請存取 Cosmos DB dotnetCosmos DB nodejs 的文件。For an in-depth description of Cosmos DB database and app creation access the documentation here for Cosmos DB dotnet or Cosmos DB nodejs.

建立資料庫帳戶Create your database account

  1. 在新的瀏覽器視窗中,登入 Azure 入口網站In a new browser window, sign in to the Azure portal.

    建立 Cosmos DB 資料庫帳戶

  2. 按一下 [建立資源] > [資料庫] > [Azure Cosmos DB]。Click Create a resource > Databases > Azure Cosmos DB

    Cosmos DB 新增帳戶頁面

  3. 在 [新增帳戶] 頁面上,提供 [訂用帳戶]、[資源群組] 資訊。On the New account page, provide Subscription, Resource group information. 為您的 [帳戶名稱] 欄位建立唯一的名稱 - 這最終會成為您的資料存取 URL 名稱的一部分。Create a unique name for your Account Name field - this eventually becomes part of your data access URL name. 針對 [API],選取 [Core(SQL)],並提供附近的 [位置] 來改善資料存取時間。For API, select Core(SQL), and provide a nearby Location to improve data access times.

  4. 然後按一下 [檢閱 + 建立]。Then click Review + Create.

  5. 驗證成功後,按一下 [建立]。Once validation has been successful, click Create.

建立帳戶需要幾分鐘的時間。The account creation takes a few minutes. 等候入口網站顯示 恭喜!Wait for the portal to display the Congratulations! 已建立您的 Azure Cosmos DB 帳戶 頁面。Your Azure Cosmos DB account was created page.

新增資料庫Add a database

重要

不同于舊版 Cosmos DB 儲存體(現在已被取代), Cosmos DB 分割的儲存體 不會自動在您的 Cosmos DB 帳戶內建立資料庫。Unlike the legacy Cosmos DB storage, which has now been deprecated, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account.

  1. 瀏覽至新建 Cosmos DB 帳戶內的 [資料總管]頁面,然後從 [建立容器] 按鈕旁邊的下拉式方塊中選擇 [建立資料庫]。Navigate to the Data Explorer page within your newly created Cosmos DB account, then choose Create Database from the drop-down box next to the Create Container button. 接著,面板會在視窗的右側開啟,您可以在此輸入新 資料庫的詳細資料。A panel will then open on the right hand side of the window, where you can enter the details for the new database.

    建立 cosmosdb 資料庫資源映射

  2. 輸入新資料庫的識別碼,並選擇性地設定輸送量 (之後可進行變更),最後按一下 [確定] 以建立您的資料庫。Enter an ID for your new database and, optionally, set the throughput (you can change this later) and finally click OK to create your database. 請記下此資料庫識別碼,稍後設定 Bot 時會用到。Make a note of this database ID for use later on when configuring your bot.

    Cosmos cosmosdb 資料庫資源詳細資料影像

  3. 現在您已建立 Cosmos DB 帳戶和資料庫,您需要複製一些值,以便將新資料庫整合到您的 Bot。Now that you have created a Cosmos DB account and a database, you need to copy over some of the values for integrating your new database into your bot. 若要取得這些資料,請瀏覽至 Cosmos DB 帳戶 [資料庫設定] 區段內的 [金鑰] 索引標籤。To retrieve these, navigate to the Keys tab within the database settings section of your Cosmos DB account. 在此頁面中,您會需要 Cosmos DB 端點 (URI) 和您的授權金鑰 (PRIMARY KEY)。From this page you will need your Cosmos DB endpoint (URI) and your authorization key (PRIMARY KEY).

    Cosmos DB 金鑰

您現在應該有一個包含資料庫的 Cosmos DB 帳戶,且已備妥下列詳細資料來設定您的 Bot。You should now have a Cosmos DB account, containing a database and have the following details ready to configure your bot.

  • Cosmos DB 端點Cosmos DB Endpoint
  • 授權金鑰Authorization Key
  • 資料庫識別碼Database ID

新增 Cosmos DB 設定資訊Add Cosmos DB configuration information

用於新增 Cosmos DB 儲存體的設定資料既簡短又簡單。Our configuration data to add Cosmos DB storage is short and simple. 請使用您在本文上一節中記下的詳細資料,設定您的端點、授權金鑰和資料庫識別碼。Use the details you made a note of in the previous part of this article to set your endpoint, authorization key and database ID. 最後,您應為容器選擇適當名稱,以在資料庫內建立可儲存您 Bot 狀態的容器。Finally, you should choose an appropriate name for the container that will be created within your database to store your bot state. 在下列範例中,此容器將稱為 "bot-storage"。In the example below the container will be called "bot-storage".

注意

您不應自行建立容器。You should not create the container yourself. 您的 Bot 會在建立其內部 Cosmos DB 用戶端時為您建立容器,以確保其已正確設定,可用於儲存 Bot 狀態。Your bot will create it for you when creating its internal Cosmos DB client, ensuring it is configured correctly for storing bot state.

將下列資訊新增至設定檔。Add the following information to your configuration file.

appsettings.jsonappsettings.json

"CosmosDbEndpoint": "<your-cosmosdb-uri>",
"CosmosDbAuthKey": "<your-authorization-key>",
"CosmosDbDatabaseId": "<your-database-id>",
"CosmosDbContainerId": "<your-container-id>"

安裝 Cosmos DB 套件Installing Cosmos DB packages

確定您有 Cosmos DB 所需的套件。Make sure you have the packages necessary for Cosmos DB.

Install-Package Microsoft.Bot.Builder.Azure

Cosmos DB 的執行Cosmos DB implementation

注意

4.6 版引進了新的 Cosmos DB 儲存提供者,「 Cosmos DB 分割儲存體」 類別,以及原始「 Cosmos DB 儲存體」 類別已遭取代。Version 4.6 introduced a new Cosmos DB storage provider, the Cosmos DB partitioned storage class, and the original Cosmos DB storage class is deprecated. 使用 Cosmos DB 儲存體 建立的容器可以搭配 Cosmos DB 分割的儲存體 使用。Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. 如需詳細資訊,請參閱 Azure Cosmos DB 中的資料分割Read Partitioning in Azure Cosmos DB for more information.

另請注意,與舊版 Cosmos DB 儲存體不同的是,Cosmos DB 分割的儲存體不會自動在您的 Cosmos DB 帳戶內建立資料庫。Also note that, unlike the legacy Cosmos DB storage, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account. 您需要 手動建立新的資料庫,但略過手動建立容器,因為 CosmosDbPartitionedStorage 會為您建立容器。You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

下列範例程式碼會使用與上面提供的記憶體儲存體範例相同的 Bot 程式碼執行。The following sample code runs using the same bot code as the memory storage sample provided above. 下列程式碼片段示範如何實作 'myStorage' 的 Cosmos DB 儲存體,以取代本機記憶體儲存體。The code snippet below shows an implementation of Cosmos DB storage for 'myStorage' that replaces local Memory storage. 記憶體儲存體已遭到註解排除,並以對 Cosmos DB 的參考取代。Memory Storage is commented out and replaced with a reference to Cosmos DB.

Startup.csStartup.cs

using Microsoft.Bot.Builder.Azure;

ConfigureServices 中,建立 CosmosDB 分割儲存體的儲存體實行個體。Within ConfigureServices, create the storage instance for CosmosDB partitioned storage.

// Use partitioned CosmosDB for storage, instead of in-memory storage.
services.AddSingleton<IStorage>(
    new CosmosDbPartitionedStorage(
        new CosmosDbPartitionedStorageOptions
        {
            CosmosDbEndpoint = Configuration.GetValue<string>("CosmosDbEndpoint"),
            AuthKey = Configuration.GetValue<string>("CosmosDbAuthKey"),
            DatabaseId = Configuration.GetValue<string>("CosmosDbDatabaseId"),
            ContainerId = Configuration.GetValue<string>("CosmosDbContainerId"),
            CompatibilityMode = false,
        }));

啟動您的 Cosmos DB botStart your Cosmos DB bot

在本機執行您的 Bot。Run your bot locally.

使用 bot framework 模擬器測試您的 Cosmos DB botTest your Cosmos DB bot with bot framework Emulator

現在啟動 bot framework 模擬器並連接到您的 bot:Now start your bot framework Emulator and connect to your bot:

  1. 在模擬器的 [歡迎使用] 索引標籤中,按一下 [ 建立新的 bot 設定] 連結。Click the Create new bot configuration link in the Emulator "Welcome" tab.
  2. 以您啟動 Bot 時顯示在網頁上的資訊,填妥欄位以連線到 Bot。Fill in fields to connect to your bot, given the information on the webpage displayed when you started your bot.

與您的 Cosmos DB bot 互動Interact with your Cosmos DB bot

傳送訊息給 Bot,Bot 就會列出所收到的訊息。Send a message to your bot, and the bot will list the messages it received. 模擬器執行中Emulator running

查看您的 Cosmos DB 資料View your Cosmos DB data

在您執行 Bot 並儲存資訊之後,我們可以在 Azure 入口網站的 [資料總管] 索引標籤下檢視所儲存的資料。After you have run your bot and saved your information, we can view the data stored in the Azure portal under the Data Explorer tab.

資料總管範例

使用 Blob 儲存體Using Blob storage

Azure Blob 儲存體是 Microsoft 針對雲端推出的物件儲存體解決方案。Azure Blob storage is Microsoft's object storage solution for the cloud. Blob 儲存體已針對儲存大量非結構化物件資料 (例如文字或二進位資料) 最佳化。Blob storage is optimized for storing massive amounts of unstructured data, such as text or binary data.

建立 Blob 儲存體帳戶Create your Blob storage account

若要在 Bot 中使用 Blob 儲存體,您需要先設定一些事項,再進入程式碼。To use Blob storage in your bot, you'll need to get a few things set up before getting into the code.

  1. 在新的瀏覽器視窗中,登入 Azure 入口網站In a new browser window, sign in to the Azure portal.

    建立 Blob 儲存體

  2. 按一下 [建立資源] > [儲存體] > [儲存體帳戶 - Blob、檔案、資料表、佇列]。Click Create a resource > Storage > Storage account - blob, file, table, queue

    Blob 儲存體新增帳戶頁面

  3. 在 [新增帳戶] 頁面中,輸入儲存體帳戶的 [名稱],針對 [帳戶種類] 選取 [Blob 儲存體],提供 [位置]、[資源群組] 和 [訂用帳戶] 資訊。In the New account page, enter Name for the storage account, select Blob storage for Account kind, provide Location, Resource group and Subscription information.

  4. 然後按一下 [檢閱 + 建立]。Then click Review + Create.

  5. 驗證成功後,按一下 [建立]。Once validation has been successful, click Create.

建立 Blob 儲存體容器Create Blob storage container

建立 Blob 儲存體帳戶之後,開啟此帳戶,做法如下:Once your Blob storage account is created, open this account by

  1. 選取資源。Selecting the resource.

  2. 現在使用儲存體總管 (預覽)「開啟」Now "Open" using Storage Explorer (preview)

    建立 Blob 儲存體容器

  3. 以滑鼠右鍵按一下 [Blob 容器],選取 [建立 Blob 容器]。Right click BLOB CONTAINERS, select Create blob container.

  4. 新增名稱。Add a name. 您將使用此名稱作為 "your-blob-storage-container-name" 的值,以供存取您的 Blob 儲存體帳戶。You will use this name for the value "your-blob-storage-container-name" to provide access to your Blob Storage account.

新增 Blob 儲存體設定資訊Add Blob storage configuration information

尋找您為 Bot 設定 Blob 儲存體所需的 Blob 儲存體金鑰,如上所示:Find the Blob Storage keys you need to configure Blob Storage for your bot as shown above:

  1. 在 Azure 入口網站中,開啟 Blob 儲存體帳戶,然後選取 [設定] > [存取金鑰]。In the Azure portal, open your Blob Storage account and select Settings > Access keys.

    尋找 Blob 儲存體金鑰

我們將使用 key1 連接字串 作為 "your-blob-storage-account-string" 值,以供存取您的 Blob 儲存體帳戶。We will use key1 Connection string as the value "your-blob-storage-account-string" to provide access to your Blob Storage account.

安裝 Blob 儲存體套件Installing Blob storage packages

如果之前未安裝,請安裝下列套件。If not previously installed, install the following packages.

Install-Package Microsoft.Bot.Builder.Azure.Blobs

Blob 儲存體執行Blob storage implementation

Blob 儲存體 是設計用來儲存 bot 狀態。Blob storage is designed to store bot state.

注意

從4.10 版, Microsoft.Bot.Builder.Azure.AzureBlobStorage 已被取代。As of version 4.10, Microsoft.Bot.Builder.Azure.AzureBlobStorage is deprecated. 使用新的 Microsoft.Bot.Builder.Azure.Blobs.BlobsStorage 位置。Use the new Microsoft.Bot.Builder.Azure.Blobs.BlobsStorage in its place.

EchoBot.csEchoBot.cs

using Microsoft.Bot.Builder.Azure.Blobs;

更新可將 "myStorage" 指向現有 Blob 儲存體帳戶的程式碼行。Update the line of code that points "myStorage" to your existing Blob Storage account.

EchoBot.csEchoBot.cs

private static readonly BlobsStorage _myStorage = new BlobsStorage("<your-azure-storage-connection-string>", "<your-blob-storage-container-name>");

將儲存體設定為指向 Blob 儲存體帳戶後,Bot 程式碼現在會儲存和擷取 Blob 儲存體中的資料。Once your storage is set to point to your Blob Storage account, your bot code will now store and retrieve data from Blob Storage.

啟動 Blob 儲存體 botStart your Blob storage bot

在本機執行您的 Bot。Run your bot locally.

啟動模擬器並聯機至您的 Blob 儲存體 botStart the Emulator and connect your Blob storage bot

接著,啟動模擬器,然後在模擬器中連接到您的 bot:Next, start the Emulator and then connect to your bot in the Emulator:

  1. 在模擬器的 [歡迎使用] 索引標籤中,按一下 [ 建立新的 bot 設定] 連結。Click the Create new bot configuration link in the Emulator "Welcome" tab.
  2. 以您啟動 Bot 時顯示在網頁上的資訊,填妥欄位以連線到 Bot。Fill in fields to connect to your bot, given the information on the webpage displayed when you started your bot.

與您的 Blob 儲存體 bot 互動Interact with your Blob storage bot

傳送訊息給 Bot,Bot 就會列出所收到的訊息。Send a message to your bot, and the bot will list the messages it receives.

模擬器測試儲存體 Bot

查看 Blob 儲存體資料View your Blob storage data

在您執行 Bot 並儲存您的資訊之後,我們可以在 Azure 入口網站的 [儲存體總管] 索引標籤下檢視。After you have run your bot and saved your information, we can view it in under the Storage Explorer tab in the Azure portal.

Blob 文字記錄儲存體Blob transcript storage

Azure Blob 文字記錄儲存體會提供一個特製化儲存體選項,讓您輕鬆地以記錄的文字記錄形式儲存和擷取使用者對話。Azure blob transcript storage provides a specialized storage option that allows you to easily save and retrieve user conversations in the form of a recorded transcript. Azure Blob 文字記錄儲存體特別適合用於自動擷取使用者輸入,以便在對 Bot 效能進行偵錯時檢查。Azure blob transcript storage is particularly useful for automatically capturing user inputs to examine while debugging your bot's performance.

注意

Python 目前不支援 Azure Blob 文字記錄儲存體Python does not currently support Azure Blob transcript storage. 雖然 JavaScript 支援 Blob 文字記錄儲存體,但下列指示僅適用于 c #。While JavaScript supports Blob transcript storage, the following directions are for C# only.

設定 Blob 文字記錄儲存體容器Set up a Blob transcript storage container

Azure Blob 文字記錄儲存體可以使用遵循上面「建立 Blob 儲存體帳戶」和「新增組態資訊」小節中詳述的步驟所建立的相同 Blob 儲存體帳戶。Azure blob transcript storage can use the same blob storage account created following the steps detailed in sections "Create your blob storage account" and "Add configuration information" above. 我們現在會新增容器來保留我們的文字記錄We now add a container to hold our transcripts

建立文字記錄容器

  1. 開啟 Azure Blob 儲存體帳戶。Open your Azure blob storage account.
  2. 按一下 [儲存體總管]。Click on Storage Explorer.
  3. 以滑鼠右鍵按一下 [Blob 容器],然後選取 [建立 Blob 容器]。Right click on BLOB CONTAINERS and select create blob container.
  4. 輸入文字記錄容器的名稱,然後選取 [確定]。enter a name for your transcript container and then select OK. (我們輸入了 mybottranscripts)(We entered mybottranscripts)

Blob 文字記錄儲存體執行Blob transcript storage implementation

下列程式碼會將文字記錄儲存體指標 _myTranscripts 連到新的 Azure Blob 文字記錄儲存體帳戶。The following code connects transcript storage pointer _myTranscripts to your new Azure blob transcript storage account. 若要使用新的容器名稱建立此連結, <your-blob-transcript-container-name> 請在 Blob 儲存體內建立新的容器,以保存您的文字記錄檔。To create this link with a new container name, <your-blob-transcript-container-name>, creates a new container within Blob storage to hold your transcript files.

Blob 文字記錄儲存體 是設計用來儲存 bot 文字記錄。Blob transcript storage is designed to store bot transcripts.

注意

從4.10 版, Microsoft.Bot.Builder.Azure.AzureBlobTranscriptStore 已被取代。As of version 4.10, Microsoft.Bot.Builder.Azure.AzureBlobTranscriptStore is deprecated. 使用新的 Microsoft.Bot.Builder.Azure.Blobs.BlobsTranscriptStore 位置。Use the new Microsoft.Bot.Builder.Azure.Blobs.BlobsTranscriptStore in its place.

echoBot.csechoBot.cs

using Microsoft.Bot.Builder.Azure.Blobs;

public class EchoBot : ActivityHandler
{
   ...

   private readonly BlobsTranscriptStore _myTranscripts = new BlobsTranscriptStore("<your-azure-storage-connection-string>", "<your-blob-transcript-container-name>");

   ...
}

在 Azure blob 文字記錄中儲存使用者對話Store user conversations in azure blob transcripts

在 Blob 容器可用於儲存文字記錄之後,您可以開始保留使用者與 Bot 的對話。After a blob container is available to store transcripts you can begin to preserve your users' conversations with your bot. 這些交談稍後可當作偵錯工具,查看使用者與 Bot 的互動方式。These conversations can later be used as a debugging tool to see how users interact with your bot. 每個模擬器 重新開機交談 都會起始新的文字記錄交談清單的建立。Each Emulator Restart conversation initiates the creation of a new transcript conversation list. 下列程式碼會在預存文字記錄檔內保留使用者交談輸入。The following code preserves user conversation inputs within a stored transcript file.

  • 使用 LogActivityAsync 可儲存目前的文字記錄。The current transcript is saved using LogActivityAsync.
  • 使用 ListTranscriptsAsync 可擷取已儲存的文字記錄。Saved transcripts are retrieved using ListTranscriptsAsync. 在此範例程式碼中,每個預存文字記錄的識別碼會儲存到名為 "storedTranscripts" 的清單中。In this sample code the Id of each stored transcript is saved into a list named "storedTranscripts". 這份清單稍後用來管理我們保留的預存 Blob 文字記錄數目。This list is later used to manage the number of stored blob transcripts we retain.

echoBot.csechoBot.cs


protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    await _myTranscripts.LogActivityAsync(turnContext.Activity);

    List<string> storedTranscripts = new List<string>();
    PagedResult<Microsoft.Bot.Builder.TranscriptInfo> pagedResult = null;
    var pageSize = 0;
    do
    {
       pagedResult = await _myTranscripts.ListTranscriptsAsync("emulator", pagedResult?.ContinuationToken);
       pageSize = pagedResult.Items.Count();

       // transcript item contains ChannelId, Created, Id.
       // save the channelIds found by "ListTranscriptsAsync" to a local list.
       foreach (var item in pagedResult.Items)
       {
          storedTranscripts.Add(item.Id);
       }
    } while (pagedResult.ContinuationToken != null);

    ...
}

管理預存 Blob 文字記錄Manage stored blob transcripts

雖然預存文字記錄可以作為偵錯工具,但經過一段時間,預存文字記錄可能成長到大於您可保留的數目。While stored transcripts can be used as a debugging tool, over time the number of stored transcripts can grow larger than you care to preserve. 以下包含的其他程式碼會使用 DeleteTranscriptAsync,從 Blob 文字記錄存放區中移除所有文字記錄 (但最後三個擷取的文字記錄項目除外)。The additional code included below uses DeleteTranscriptAsync to remove all but the last three retrieved transcript items from your blob transcript store.

echoBot.csechoBot.cs


protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    await _myTranscripts.LogActivityAsync(turnContext.Activity);

    List<string> storedTranscripts = new List<string>();
    PagedResult<Microsoft.Bot.Builder.TranscriptInfo> pagedResult = null;
    var pageSize = 0;
    do
    {
       pagedResult = await _myTranscripts.ListTranscriptsAsync("emulator", pagedResult?.ContinuationToken);
       pageSize = pagedResult.Items.Count();

       // transcript item contains ChannelId, Created, Id.
       // save the channelIds found by "ListTranscriptsAsync" to a local list.
       foreach (var item in pagedResult.Items)
       {
          storedTranscripts.Add(item.Id);
       }
    } while (pagedResult.ContinuationToken != null);

    // Manage the size of your transcript storage.
    for (int i = 0; i < pageSize; i++)
    {
       // Remove older stored transcripts, save just the last three.
       if (i < pageSize - 3)
       {
          string thisTranscriptId = storedTranscripts[i];
          try
          {
             await _myTranscripts.DeleteTranscriptAsync("emulator", thisTranscriptId);
           }
           catch (System.Exception ex)
           {
              await turnContext.SendActivityAsync("Debug Out: DeleteTranscriptAsync had a problem!");
              await turnContext.SendActivityAsync("exception: " + ex.Message);
           }
       }
    }
    ...
}

以下連結提供關於 Azure Blob 文字記錄儲存體的詳細資訊The following link provides more information concerning Azure Blob Transcript Storage

其他資訊Additional Information

使用 eTag 管理並行Manage concurrency using eTags

在 Bot 程式碼範例中,我們會將每個 IStoreItemeTag 屬性設定為 *In our bot code example we set the eTag property of each IStoreItem to *. 存放區物件的 eTag (實體標記) 成員在 Cosmos DB 中用來管理並行作業。The eTag (entity tag) member of your store object is used within Cosmos DB to manage concurrency. 如果另一個 Bot 執行個體變更了 Bot 所寫入的同一個儲存體中的物件,eTag 會告知資料庫該採取什麼動作。The eTag tells your database what to do if another instance of the bot has changed the object in the same storage that your bot is writing to.

最後寫入者優先 - 允許覆寫Last write wins - allow overwrites

星號 (*) 的 eTag 屬性值指出最後寫入者優先。An eTag property value of asterisk (*) indicates that the last writer wins. 建立新的資料存放區時,您可以將屬性的 eTag 設定為 *,以指出您之前沒有儲存過正在寫入的資料或您想要最後寫入的資料覆寫之前已儲存的任何屬性。When creating a new data store, you can set eTag of a property to * to indicate that you have not previously saved the data that you are writing, or that you want the last writer to overwrite any previously saved property. 如果您的 Bot 沒有並行的問題,針對正在寫入的任何資料,將其 eTag 屬性設定為 *,以允許覆寫。If concurrency is not an issue for your bot, setting the eTag property to * for any data that you are writing enables overwrites.

維護並行和防止覆寫Maintain concurrency and prevent overwrites

將資料儲存到 Cosmos DB 時,如果您想要防止並行存取屬性,以及避免覆寫另一個 Bot 執行個體所做的變更,請對 eTag 使用 * 以外的值。When storing your data into Cosmos DB, use a value other than * for the eTag if you want to prevent concurrent access to a property and avoid overwriting changes from another instance of the bot. 當 Bot 嘗試儲存狀態資料且 eTag 與儲存體中的 eTag 值不同時,Bot 會收到含有 etag conflict key= 訊息的錯誤回應。The bot receives an error response with the message etag conflict key= when it attempts to save state data and the eTag is not the same value as the eTag in storage.

根據預設,每次 Bot 寫入到儲存體物件時,Cosmos DB 存放區會檢查其 eTag 屬性是否相同,然後在每次寫入之後將該屬性更新為新的唯一值。By default, the Cosmos DB store checks the eTag property of a storage object for equality every time a bot writes to that item, and then updates it to a new unique value after each write. 如果寫入的 eTag 屬性與儲存體中的 eTag 不相符,這表示另一個 Bot 或執行緒已變更資料。If the eTag property on write doesn't match the eTag in storage, it means another bot or thread changed the data.

例如,假設您想要 Bot 編輯已儲存的附註,但不想覆寫另一個 Bot 執行個體所作的變更。For example, let's say you want your bot to edit a saved note, but you don't want your bot to overwrite changes that another instance of the bot has done. 如果另一個 Bot 執行個體已進行編輯,則您想要 使用者編輯最新更新的版本。If another instance of the bot has made edits, you want the user to edit the version with the latest updates.

首先,建立會實作 IStoreItem 的類別。First, create a class that implements IStoreItem.

EchoBot.csEchoBot.cs

public class Note : IStoreItem
{
    public string Name { get; set; }
    public string Contents { get; set; }
    public string ETag { get; set; }
}

接下來,建立儲存體物件來建立初始附註,並將物件新增到存放區。Next, create an initial note by creating a storage object, and add the object to your store.

EchoBot.csEchoBot.cs

// create a note for the first time, with a non-null, non-* ETag.
var note = new Note { Name = "Shopping List", Contents = "eggs", ETag = "x" };

var changes = Dictionary<string, object>();
{
    changes.Add("Note", note);
};
await NoteStore.WriteAsync(changes, cancellationToken);

然後,稍後存取並更新附註,將它的 eTag 保持為從存放區讀取的原狀。Then, access and update the note later, keeping its eTag that you read from the store.

EchoBot.csEchoBot.cs

var note = NoteStore.ReadAsync<Note>("Note").Result?.FirstOrDefault().Value;

if (note != null)
{
    note.Contents += ", bread";
    var changes = new Dictionary<string, object>();
    {
         changes.Add("Note1", note);
    };
    await NoteStore.WriteAsync(changes, cancellationToken);
}

如果存放區中的附註在您寫入變更之前已經更新,對 Write 的呼叫將會擲回例外狀況。If the note was updated in the store before you write your changes, the call to Write will throw an exception.

若要維護並行,一律從儲存體讀取屬性,然後修改所讀取的屬性,如此即可維護 eTagTo maintain concurrency, always read a property from storage, then modify the property you read, so that the eTag is maintained. 如果您從存放區讀取使用者資料,回應將會包含 eTag 屬性。If you read user data from the store, the response will contain the eTag property. 如果您變更資料並將更新的資料寫入存放區,則您的要求應該包含 eTag 屬性且它必須指定與您之前讀取相同的值。If you change the data and write updated data to the store, your request should include the eTag property that specifies the same value as you read earlier. 不過,寫入其 eTag 設定為 * 的物件,將允許寫入可覆寫任何其他變更。However, writing an object with its eTag set to * will allow the write to overwrite any other changes.

後續步驟Next steps

既然您已經知道如何直接從儲存體讀取和寫入,現在我們來看看如何使用狀態管理員來為您執行這些動作。Now that you know how to read read and write directly from storage, lets take a look at how you can use the state manager to do that for you.