Botframework v4:瀑布stepcontext结果.如何简化? [英] Botframework v4: waterfall stepcontext result. How to simplify?

查看:69
本文介绍了Botframework v4:瀑布stepcontext结果.如何简化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对话框,根据属性,数字要么提示用户,要么确认提示用户.然后,它检查瀑布步上下文结果的类型是十进制还是布尔值.它按预期工作,但我认为它过于复杂并且容易出错.

I have this dialog that either number prompt the user or confirm prompt the user depending on a property. It then check the type of waterfall stepcontext result if it is decimal or bool. It is working as intented but i think it is overcomplicated and prone to error.

是否有更好的方法可以做到这一点?这是代码:

Is there a better way to do this? Here is the code:

public class LoanCalculator : WaterfallDialog
{
    public LoanCalculator(string dialogId, IEnumerable<WaterfallStep> steps = null)
        : base(dialogId, steps)
    {
        AddStep(async (stepContext, cancellationToken) =>
        {
            // check if the property has a price
            var userstate = await (stepContext.Context.TurnState["BasicAccessors"] as BasicAccessors).BasicUserStateAccessor.GetAsync(stepContext.Context);

            // if zero, decimal prompt
            if (userstate.PropertyPrice == 0)
            {
                return await stepContext.PromptAsync(
                "numberPromptDecimal",
                new PromptOptions
                {
                    Prompt = MessageFactory.Text("Indicate price of property."),
                    RetryPrompt = MessageFactory.Text("Please enter a valid amount."),
                });
            }
            else
            {
                // if not zero bool prompt confirm if user wants to change its value or not
                return await stepContext.PromptAsync(
                "confirmPrompt",
                new PromptOptions
                {
                    Prompt = MessageFactory.Text($"Property price is {userstate.PropertyPrice}. Is this correct?"),
                });
            }
        });

        AddStep(async (stepContext, cancellationToken) =>
        {
            var userstate = await (stepContext.Context.TurnState["BasicAccessors"] as BasicAccessors).BasicUserStateAccessor.GetAsync(stepContext.Context);

            // if decimal prompt
            if (stepContext.Result is decimal)
            {
                stepContext.Values["price"] = Convert.ToDecimal(stepContext.Result);
                return await stepContext.NextAsync();
            }
            // if bool prompt
            else if (stepContext.Result is bool)
            {
                // if user does not want to change value
                if ((bool)stepContext.Result)
                {
                    stepContext.Values["price"] = userstate.PropertyPrice;
                    return await stepContext.NextAsync();
                }
                // if user want to change value, make value zero and restart dialog
                else
                {
                    userstate.PropertyPrice = 0;
                    return await stepContext.ReplaceDialogAsync(Id);
                }
            }
            else
            {
                // i dont know what to do with this so i just restart dialog
                return await stepContext.ReplaceDialogAsync(Id);
            }
        });

        AddStep(async (stepContext, cancellationToken) =>
        {
            // if stepcontext values is not equals to null
            if (!stepContext.Values["price"].Equals(null))
            {
                return await stepContext.PromptAsync(
                "numberPromptDecimal",
                new PromptOptions
                {
                    Prompt = MessageFactory.Text("Indicate amount of loan."),
                    RetryPrompt = MessageFactory.Text("Please enter a valid amount."),
                });
            }
            else
            {
                // again dont know what to odo with this
                await stepContext.Context.SendActivityAsync(MessageFactory.Text($"oops"));
                return await stepContext.ReplaceDialogAsync(Id);
            }
        });

        AddStep(async (stepContext, cancellationToken) =>
        {
            // continue
        });
    }

    public static string Id = "loanCalculator";

    public static LoanCalculator Instance { get; } = new LoanCalculator(Id);
}

推荐答案

我建议分支为两个可能的子对话框.这些子对话框可以通过将价格传递给EndDialogAsync来将价格返回到顶级对话框,而不是访问stepContext.Values["price"].

I recommend branching into two possible sub-dialogs. Rather than accessing stepContext.Values["price"], these sub-dialogs could return the price to the top-level dialog by passing it through EndDialogAsync.

我剩下的答案会问您关于您的代码的问题,而您并不是特别在问这些问题.

由于您要提出建议,我应该提到Bot Framework示例很少扩展WaterfallDialog.如果要创建自己的对话框类,从ComponentDialog继承然后以WaterfallDialog作为其开始组件是更标准的,但是对于您而言,我不确定您根本不需要自定义对话框类.而且,如果您确实扩展了WaterfallDialog,则在构造函数中具有相同的两个参数有点奇怪,因为您肯定不希望将任何步骤传递给它.为什么不这样做呢?

Since you're asking for recommendations, I should mention that the Bot Framework samples seldom if ever extend WaterfallDialog. If you want to make your own dialog class it's more standard to inherit from ComponentDialog and then have a WaterfallDialog as its starting component, but in your case I'm not sure you need a custom dialog class at all. And if you do extend WaterfallDialog it's a bit strange to have the same two parameters in your constructor since you're surely not expecting to have any steps passed into it. Why not just do this?

public LoanCalculator() : base(Id, null)

这篇关于Botframework v4:瀑布stepcontext结果.如何简化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆