Получение данных TurnState из DialogContext - PullRequest
0 голосов
/ 05 февраля 2019

Я использую BotBuilder SDK v4.Вот объяснение ниже (игнорируя некоторый дополнительный код).

На моем боте OnTurnAsync Я вызываю один из моих диалогов следующим образом:

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
    var state = await _accessors.TurnStateAccessor.GetAsync(turnContext, () => new TurnState()).ConfigureAwait(false);
    var dialogContext = await _dialogs.CreateContextAsync(turnContext).ConfigureAwait(false);       
    await dialogContext.BeginDialogAsync(nameof(SomeDialog)).ConfigureAwait(false);

    //remaining code..
}

Вызов успешен, и он достигаетдиалог.Ниже приведен код.

public override Task<DialogTurnResult> BeginDialogAsync(DialogContext outerDc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
    outerDc.ContinueDialogAsync();
    return base.BeginDialogAsync(outerDc, options, cancellationToken);
}

public override Task<DialogTurnResult> ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken = default(CancellationToken))
{
    var turnState = outerDc.Context.TurnState["ConversationState"]; //access turn state here
    outerDc.EndDialogAsync();    
    return base.ContinueDialogAsync(outerDc, cancellationToken);
}

Внутри ContinueDialogAsync Я пытаюсь получить доступ к объекту контекста диалога outerDc, который содержит данные о состоянии моего бота, как я настроил и вижу в окне немедленного просмотра.

outerDc.Context.TurnState Count = 3
    [0]: {[BotIdentity, System.Security.Claims.ClaimsIdentity]}
    [1]: {[Microsoft.Bot.Connector.IConnectorClient, Microsoft.Bot.Connector.ConnectorClient]}
    [2]: {[ConversationState, Microsoft.Bot.Builder.BotState+CachedBotState]} outerDc.Context.TurnState["ConversationState"] {Microsoft.Bot.Builder.BotState.CachedBotState}
    Hash: "{}"
    State: Count = 2

Вот выражение QuickWatch, и выделенное значение как раз то, что мне нужно.

enter image description here

Когда я пытаюсь использоватьвыражение ((Microsoft.Bot.Builder.BotState.CachedBotState)outerDc.Context.TurnState["ConversationState"]).State в моем коде, кажется, CachedBotState не является частью пространства имен / пакета.Также кажется, что Microsoft.Bot.Builder.BotState.CachedBotState является частью пакета Microsoft.Bot.Builder.Core nuget, который все еще находится на стадии предварительного просмотра.

Я знаю, что могу передать объект TurnState в качестве дополнительного параметра из OnTurnAsync моемудиалог.Но я хочу получить к нему доступ через контекст диалога, когда он показывает, что он уже там.Есть ли способ сделать это?

Пожалуйста, дайте мне знать, если я могу уточнить подробнее.

1 Ответ

0 голосов
/ 05 февраля 2019

Во-первых, CachedBotState - это внутренняя деталь реализации, а не та, которую вы когда-либо ожидали использовать.Точно так же вам не следует копаться в TurnState и ожидать, что вы будете работать со значениями внутри него, которые не находятся под вашим контролем, поскольку это также просто деталь реализации того, как состояние бота поддерживает значения для объема хода.Я бы порекомендовал вам отказаться от этого подхода, потому что, в конечном счете, вся реализация может измениться в следующей версии (поскольку это внутренние детали и не подчиняются правилам semver), и в результате ваш код будет поврежден.

Вместо этого,то, что вы должны сделать, это передать ваш IStatePropertyAccessor<TurnState> конструктору SomeDialog, когда вы его создаете и добавляете в DialogSet.Это дает SomeDialog возможность чтения / записи этого конкретного свойства для данного хода, и ваш код изменится, чтобы выглядеть следующим образом:

public override Task<DialogTurnResult> ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken = default(CancellationToken))
{
    // Access state via the property accessor rather than trying to access raw internals of bot state management
    var turnState = await _turnStatePropertyAccessor.GetAsync(outerDc.Context);

    outerDc.EndDialogAsync();    

    return base.ContinueDialogAsync(outerDc, cancellationToken);
}
...