代码之家  ›  专栏  ›  技术社区  ›  Souvik Ghosh

在Bot框架中使用FormFlow对话框

  •  3
  • Souvik Ghosh  · 技术社区  · 8 年前

    DialogContext.Begin , DialogContext.End 和 DialogContext.Continue . 一切正常,但现在我想在对话中实现一个FormFlow。我提到了这个链接- https://docs.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-formflow?view=azure-bot-service-3.0

    我在Github上发布了这个( https://github.com/MicrosoftDocs/bot-docs/issues/227 )基于这个解决方案,这就是我所尝试的-

    [Serializable]
    public class HelpForm
    {
        public string FullName { get; set; }
        public string EmailID { get; set; }
        public string Question { get; set; }
        public DateTime BestTimeToContact { get; set; }
        public List<Priority> Priority { get; set; }
        public static IForm<HelpForm> BuildForm()
        {
            return new FormBuilder<HelpForm>()
                .Message("Please fill out the details as prompted.")
                .Build();
        }
    }
    
    public enum Priority
    {
        Low,
        Medium,
        High
    }
    

    在我的 OnTurn 我的机器人事件,我正在做这样的事情-

    await Microsoft.Bot.Builder.Classic.Dialogs.Conversation.SendAsync(context, () => FormDialog.FromForm(HelpForm.BuildForm)); //context is of type ITurnContext

    抱歉,我的机器人代码有问题。

    还有,这个链接- https://github.com/Microsoft/botbuilder-dotnet/wiki/Using-Classic-V3-Dialogs-with-V4-SDK 这么说 Microsoft.Bot.Builder.Classic 有什么需要帮忙的吗?

    更新

    System.Runtime.Serialization.SerializationException: Type 'System.RuntimeType' in Assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' is not marked as serializable. . 尽管我的HelpForm类标记为 Serializable

    查看的元数据 FormFlow 可串行化 属性。

    enter image description here

    请注意,如果这就是错误的原因。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Eric Dahlvang    7 年前

    Bot Builder V3版 组合流程 Bot.Builder.Community.Dialogs.FormFlow 图书馆。

    你的 帮助表单 可以用与其他V4组件对话框相同的方式添加到V4对话框集中:

    _dialogs.Add(FormDialog.FromForm(HelpForm.BuildForm));
    

    下面是一个更完整的示例:

    public class TestEchoBotAccessors
    {
        public TestEchoBotAccessors(ConversationState conversationState)
        {
            ConversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
        }
    
        public ConversationState ConversationState { get; }
        public IStatePropertyAccessor<DialogState> ConversationDialogState { get; set; }
    }
    

    Startup.cs配置服务:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddBot<TestEchoBotBot>(options =>
        {
            IStorage dataStore = new MemoryStorage();
            options.State.Add(new ConversationState(dataStore));
            options.Middleware.Add(new AutoSaveStateMiddleware(options.State.ToArray()));
    
            var secretKey = Configuration.GetSection("botFileSecret")?.Value;
            var botFilePath = Configuration.GetSection("botFilePath")?.Value;
    
            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            var botConfig = BotConfiguration.Load(botFilePath ?? @".\TestEchoBot.bot", secretKey);
            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));
    
            // Retrieve current endpoint.
            var environment = _isProduction ? "production" : "development";
            var service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();
            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }
    
            options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);
        });
    
        services.AddSingleton(sp =>
        {
            var options = sp.GetRequiredService<IOptions<BotFrameworkOptions>>().Value;
            var conversationState = options.State.OfType<ConversationState>().FirstOrDefault();
            var accessors = new TestEchoBotAccessors(conversationState)
            {
                ConversationDialogState = conversationState.CreateProperty<DialogState>("DialogState")
            };
            return accessors;
        });
    }
    

    机器人代码:

    public class TestEchoBotBot : IBot
    {
        private readonly TestEchoBotAccessors _accessors;
        private DialogSet _dialogs;
    
        public TestEchoBotBot(TestEchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            if (loggerFactory == null)
            {
                throw new System.ArgumentNullException(nameof(loggerFactory));
            }
    
            _dialogs = new DialogSet(accessors.ConversationDialogState);
            _dialogs.Add(FormDialog.FromForm(HelpForm.BuildForm));
            _accessors = accessors ?? throw new System.ArgumentNullException(nameof(accessors));
        }
    
        public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (turnContext.Activity.Type == ActivityTypes.Message)
            {
                var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
                if (turnContext.Activity.Text?.ToUpper() == "HELP")
                {
                    await dialogContext.BeginDialogAsync(typeof(HelpForm).Name, null, cancellationToken);
                }
                else
                {
                    var dialogResult = await dialogContext.ContinueDialogAsync(cancellationToken);
                    if ((dialogResult.Status == DialogTurnStatus.Cancelled || dialogResult.Status == DialogTurnStatus.Empty))
                    {
                        var responseMessage = $"You sent '{turnContext.Activity.Text}'\n";
                        await turnContext.SendActivityAsync(responseMessage);
                    }
                }                
            }
        }
    }
    
        2
  •  2
  •   Dana V    7 年前

    不幸的是,正如您所发现的,FormFlow不适用于v4。

    V4附带了一个非常结构化的瀑布式对话框,可用于实现类似于FormFlow的功能。样品 here 演示如何使用瀑布式对话框向用户询问一系列问题,如姓名、年龄和地址。Prompt对话框类特别适合这种类型的任务。您可以在对话框的末尾实现一个确认提示,以模拟FormFlow的确认。