如何通过验证来处理对话框中的中断?

时间:2019-03-29 10:16:19

标签: c# botframework

在一种情况下试图处理“预期的”中断的尝试被忽略,而有利于验证用户输入。

我有一个具有3种不同情况的机器人(SDKv4)。我已经将每种情况都提取到从ComponentDialog继承的自己的类中。在这里,我可以包含与每种情况相关的所有瀑布步骤。

public class ScenarioOne : ComponentDialog
{
    public ScenarioOne()
    {
        var steps = new WaterfallStep[]
        {
            GetInputStepAsync,
            ProcessInputStepAsync
        };

        AddDialog(new WaterfallDialog(nameof(ScenarioOne), steps));
    }

    private async Task<DialogTurnResult> GetInputStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        // Prompt for data here.
    }
}

在一种情况下,我要求用户输入17个字符。我应用了一个自定义验证器,并将其分配给相关的瀑布步骤。

public class StepOneValidator
{
    public async Task<bool> ValidateAsync(PromptValidatorContext<string> promptContext, CancellationToken cancellationToken)
    {
        // Validation logic here.
    }
}

验证器已在Bot中注册:

public ExampleBot(ExampleBotAccessors accessors)
{
    _dialogs = new DialogSet(accessor.Dialog);
    _dialogs
        .Add(new TextPrompt("step-one", new CustomValidator().ValidateAsync));

    _dialogs.Add(new ScenarioOne());
}

我想处理这种特定情况下的预期中断,例如more infohelp,以帮助用户使用预期输入的格式。我从文档中了解到,我可以在OnTurnAsync处理程序中全局拦截响应,但这将应用于我想避免的所有响应。

我正在关注的文档可以在here中找到。

可以将类似的东西添加到ProcessInputStepAsync方法中以检查预期的中断:

public async Task<DialogTurnResult> ProcessInputStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    var response = ((string)stepContext.Result).Trim().ToLowerInvariant();
    if (response.Equals("help")
    {
        // Send activity and replace dialog with main dialog.
    }
}

我希望验证者忽略预期的中断。有没有一种方法可以在验证器中不对它们进行硬编码?

1 个答案:

答案 0 :(得分:0)

您可以覆盖OnContinueDialogAsync上的ComponentDialog方法,并在那里执行中断逻辑。作为检查的一部分,您可以看到活动对话框是什么,如果是TextInput,则处理中断。下面是一个示例。

public class ScenarioOne : ComponentDialog
{
    private static string textInputId = "text";

    public ScenarioOne()
    {
        var steps = new WaterfallStep[]
        {
            GetInputStepAsync,
            ProcessInputStepAsync
        };

        AddDialog(new WaterfallDialog(nameof(ScenarioOne), steps));
        AddDialog(new TextPrompt(textInputId));
    }

    private async Task<DialogTurnResult> GetInputStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        // Prompt for data here.
    }

    protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
    {
        string text = innerDc.Context.Activity.Text;

        if (text.ToLower() == "help" && innerDc.ActiveDialog.Id != textInputId)
        {
            //do interruption
        }
        return await base.OnContinueDialogAsync(innerDc, cancellationToken);
    }
}