c# - 回调 FormDialog 指定的次数

标签 c# botframework

我正在尝试创建一个向用户提问的机器人。启动时,机器人会询问用户将采取哪个选择:

  1. 开始测验(之后他必须选择测验的主题和难度);
  2. 查看他上次测验的得分;
  3. 重置分数。

测验的内容位于 XML 文件中。我已经将问题和答案存储在一个结构中。

FormBuilder 是:

[Serializable]
public class QuizQuestionsLoader
{
    public QuizQuestion Question { get; set; }

    public static IForm<QuizQuestionsLoader> QuestionLoaderForm(QuizQuestion question)
    {
        return new FormBuilder<QuizQuestionsLoader>()
            .Field(new FieldReflector<QuizQuestionsLoader>(nameof(Question))
                .SetType(null)
                .SetDefine(async (state, field) =>
                {
                    field
                        .AddDescription(state.Question.QuestionText, state.Question.QuestionText)
                        .AddTerms(state.Question.QuestionText, state.Question.QuestionText);

                    return true;
                }))
            .AddRemainingFields()
            .Build();
    }
}

因此,我创建了一个带有开关的 IDialog,用于确定用户做出的选择。如果用户选择开始测验,DefaultCase 将被激活:

new DefaultCase<QuizChoices?, IDialog<string>>((context, value) =>
                {
                    return Chain.From(() => FormDialog.FromForm(QuizStart.QuizForm, FormOptions.PromptInStart))
                        .Select(c => c.category)
                        .ContinueWith(async (ctx, res) =>
                        {
                            CategoryOptions? category = await res;
                            IList<QuizQuestion> questions = QuestionsLoader.LoadQuestions(category.Value.ToString().ToLowerInvariant()).ToList();

                            QuizQuestion currentQuestion = questions[0];
                            var questionsDialogs = Chain.From(() => FormDialog.FromForm(() => { return QuizQuestionsLoader.QuestionLoaderForm(currentQuestion); })).PostToUser();

                            for (int i = 1; i < questions.Count(); i++)
                            {
                                currentQuestion = questions[i];

                                questionsDialogs.ContinueWith(async (forctx, fores) =>
                                {
                                    await fores;
                                    return Chain.From(() => FormDialog.FromForm(() => { return QuizQuestionsLoader.QuestionLoaderForm(currentQuestion); }));
                                }).PostToUser();
                            }

                            return Chain.Return(questionsDialogs).Unwrap();
                    })
                    .ContinueWith(async (ctx, res) =>
                    {
                        await res;
                        return Chain.Return("Quiz fini !");
                    });
                })

我想向用户显示 10 个问题,这就是为什么我认为召回 FormBuilder 是个好主意,因为我不知道如何以其他方式做到这一点。当我构建并运行此程序时,在选择难度后,Bot Framework 模拟器会发送 500 内部服务器错误。

这就是为什么我试图记忆起一个“测试”FormBuilder,它由一条简单的消息和三个选项组成,看看我是否可以用 for 循环记忆起 FormDialog。 这是表单构建器:

public enum TestOptions
{
    A, B, C
}

[Serializable]
public class Test
{
    public TestOptions? choice;

    public static IForm<Test> TestForm()
    {
        return new FormBuilder<Test>()
            .Message("Test")
            .Field(nameof(choice))
            .Build();
    }
}

这是 IDialog:

return Chain.From(() => FormDialog.FromForm(Test.TestForm, FormOptions.PromptInStart))
                        .ContinueWith(async(ctx, res) =>
                        {
                            await res;
                            var testDialog = Chain.From(() => FormDialog.FromForm(() => { return Test.TestForm(); })).PostToUser();

                            for (int i = 0; i < 2; i++)
                            {
                                testDialog.ContinueWith<Test, Test>(async (forctx, fores) =>
                                {
                                    await fores;
                                    return Chain.From(() => FormDialog.FromForm(Test.TestForm, FormOptions.PromptInStart));
                                });
                            }

                            return Chain.Return(testDialog);
                        })

这样,FormDialog将显示一次,但我看到执行了for循环。但是,testDialog 变量为空。

那么,你知道我如何才能继续正确记忆我的 FormBuilder 以在 Bot Framework Emulator 上提出 10 个问题吗?

非常感谢!

最佳答案

我添加了一个示例,说明如何使用此 commit 迭代测验中的问题。 。它使用名为 FoldDialog 的可链接对话框来按顺序调用一系列对话框并聚合响应:

var quiz = Chain
            .PostToChain()
            .Select(_ => "how many questions?")
            .PostToUser()
            .WaitToBot()
            .Select(m => int.Parse(m.Text))
            .Select(count => Enumerable.Range(0, count).Select(index => Chain.Return($"question {index + 1}?").PostToUser().WaitToBot().Select(m => m.Text)))
            .Fold((l, r) => l + "," + r)
            .Select(answers => "your answers were: " + answers)
            .PostToUser();

它允许创建这样的脚本:

"hello",
"how many questions?",
"3",
"question 1?",
"A",
"question 2?",
"B",
"question 3?",
"C",
"your answers were: A,B,C"

关于c# - 回调 FormDialog 指定的次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37986146/

相关文章:

C# Random 不像 random 那样工作

javascript - Bot Framework [Node.js] Bot 不匹配单词

C# 使用 json.net 反序列化 JSON,想要提取数组索引作为模型属性

c# - Hangfire 作业插入对应用程序 API 性能的影响

node.js - 使用 NodeJS 中的 Microsoft Bot Framework 将 Excel 内容作为附件发送

c# - 客户端和服务器位于同一 Web 应用程序中的 Azure Bot 项目

c# - 从另一个对话框启动 FormFlow 对话框

botframework - Azure BOT 框架,将 QnA Maker 与 LUIS 集成

c# - 三元运算符语法

c# - 动态增加数组中元素的数量