如何运行主动对话框

时间:2019-08-29 00:21:12

标签: c# botframework

我想启动一个主动对话框。我尝试修改此主动消息示例https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/16.proactive-messages

我已通过以下方式更改了此示例:

private async Task BotCallback(ITurnContext turnContext, CancellationToken)  
{  
    _dialog.RunAsync(turnContext, _conversationState<DialogState>("DialogState"), cancellationToken);  
     try  
     {  
        await _conversationState.SaveChangesAsync(turnContext, true, cancellationToken);  
     }  
     catch(Exception ex)  
     {  
        _logger.LogError($"{nameof(_conversationState)}, {ex.Message}");  
     }  
}  

并且对话框开始,但是当bot从用户处获得下一条消息时,它无法继续此对话框并抛出以下异常:

  

Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter:错误:>捕获到异常:DialogContext.ContinueDialogAsync():无法继续>对话框。找不到ID为“ LearnDialog”的对话框。”。

我使用DI通过构造函数注入对话框
构造函数:

public NotifiController(IBotFrameworkHttpAdapter adapter, IStorage storage, LearnDialog dialog, ConversationState conversationState)  
        {  
            _adapter = (BotFrameworkHttpAdapter)adapter ?? throw new ArgumentNullException(nameof(adapter));  
            _storage = storage ?? throw new ArgumentNullException(nameof(storage));  
            _dialog = dialog ?? throw new ArgumentNullException(nameof(dialog));  
        }  

Startup.cs:

public void ConfigureServices(IServiceCollection services)  
        {        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
            // Create the Bot Framework Adapter with error handling enabled.  
            services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();  
            services.AddSingleton<IStorage, MemoryStorage>();  
            services.AddSingleton < UserState>();  
            services.AddSingleton<ConversationState>();  
            services.AddSingleton<MainDialog>();  
            services.AddSingleton<LearnDialog>();  
            services.AddTransient<IBot, DialogBot<MainDialog>();  
        }  

1 个答案:

答案 0 :(得分:0)

我遇到问题的原因是,尽管通常是从MainDialog运行,但我还是尝试直接运行LearnDialog。 解决方法如下: 在MainDialog类中,定义允许外部代码更改启动对话框的特殊方法:

public void SetLearnDialogAsInitial(bool state) =>
    InitialDialogId = state ? nameof(LearnDialog) : nameof(WaterfallDialog);

将MainDialog放到调用主动对话框的Class上,在我的情况下是NotifyController,就像发送主动消息的源示例中一样

public class NotifiController : ControllerBase
    {

        public NotifiController(IBotFrameworkHttpAdapter adapter, IStorage storage, MainDialog dialog, ConversationState conversationState, ILogger<NotifiController> logger)
        {
            _adapter = (BotFrameworkHttpAdapter)adapter ?? throw new ArgumentNullException(nameof(adapter));
            _storage = storage ?? throw new ArgumentNullException(nameof(storage));
            _mainDialog = dialog ?? throw new ArgumentNullException(nameof(dialog));
            _conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
            _appId = Guid.NewGuid().ToString();
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
    }

在BotCalback方法中,将LearnDialog设置为MainDialog的“初始”对话框,然后运行MainDialog:

private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)   
        {
            _mainDialog.SetLearnDialogAsInitial(true);
            var dialog = (Dialog)_mainDialog;
            await dialog.RunAsync(turnContext, _conversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
//              _mainDialog.SetLearnDialogAsInitial(false);
            try
            {
                await _conversationState.SaveChangesAsync(turnContext, true, cancellationToken);
            }
            catch(Exception ex)
            {
                _logger.LogError($"{nameof(_conversationState)}, {ex.Message}");
            }
        }

对我有用。