我希望我的机器人向用户询问位置。当用户回答“靠近我”时,机器人应继续进行下一步,而当用户回答“其他地方”时,机器人应在进行下一步之前向用户询问具体位置。我怎么在机器人模拟器中遇到错误。当用户选择“靠近我”或“其他地方”时,它将不会发送。
namespace FinancialPlannerBot.Dialogs.RealEstate
{
public class MainRealEstateDialog : WaterfallDialog
{
public MainRealEstateDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
{
AddStep(async (stepContext, cancellationToken) =>
{
return await stepContext.PromptAsync("choicePrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply("Would you like to buy or rent?"),
Choices = new[] {new Choice {Value = "Buy"},
new Choice {Value = "Rent"}
}.ToList()
});
});
AddStep(async (stepContext, cancellationToken) =>
{
var buyOrRent = stepContext.Result as FoundChoice;
var state = await (stepContext.Context.TurnState["FPBotAccessors"] as FPBotAccessors).FPBotStateAccessor.GetAsync(stepContext.Context);
state.BuyOrRent = buyOrRent.Value;
return await stepContext.PromptAsync("choicePrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply("What kind of real estate do you want?"),
Choices = new[] {new Choice {Value = "Type 1"},
new Choice {Value = "Type 2"},
new Choice {Value = "Type 3"}
}.ToList()
});
});
AddStep(async (stepContext, cancellationToken) =>
{
var realEstateType = stepContext.Result as FoundChoice;
var state = await (stepContext.Context.TurnState["FPBotAccessors"] as FPBotAccessors).FPBotStateAccessor.GetAsync(stepContext.Context);
state.RealEstateType = realEstateType.Value;
return await stepContext.PromptAsync("choicePrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply("Which location are you considering?"),
Choices = new[] {new Choice {Value = "Near me"},
new Choice {Value = "Somewhere else"}
}.ToList()
});
});
AddStep(async (stepContext, cancellationToken) => //ERROR
{
var nearOrSomewhereElse = stepContext.Result as FoundChoice;
var state = await (stepContext.Context.TurnState["FPBotAccessors"] as FPBotAccessors).FPBotStateAccessor.GetAsync(stepContext.Context);
state.NearOrSomewhereElse = nearOrSomewhereElse.Value;
if (state.NearOrSomewhereElse == "Somewhere else")
{
await stepContext.PromptAsync("textPrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply("Which location are you considering?")
});
}
return await stepContext.ContinueDialogAsync();
});
AddStep(async (stepContext, cancellationToken) =>
{
var nearOrSomewhereElse = stepContext.Result as FoundChoice;
var state = await (stepContext.Context.TurnState["FPBotAccessors"] as FPBotAccessors).FPBotStateAccessor.GetAsync(stepContext.Context);
state.NearOrSomewhereElse = nearOrSomewhereElse.Value;
return await stepContext.PromptAsync("choicePrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply($"Please indicate the size of {state.RealEstateType}"),
Choices = new[] {new Choice {Value = "Size 1"},
new Choice {Value = "Size 2"},
new Choice {Value = "Size 3"}
}.ToList()
});
});
}
public static string Id = "MainRealEstateDialog";
public static MainRealEstateDialog Instance { get; }= new MainRealEstateDialog(Id);
}
}
答案 0 :(得分:1)
嗯,这里有几个问题……
首先,在处理"Near me"
与"Somewhere else"
的步骤中需要if / else,因为您只想在“其他地方”提示时,对吗?
第二,因为该步骤现在将根据所采用的路径返回不同的结果,所以下一步需要准备好处理不同的传入结果。现在,最后一步是有问题的,因为它当前假设它将要收到FoundChoice
,但不会。在textPrompt
路径的情况下,它将从"Somewhere else"
接收文本,或者由于手动ContinueDialog
调用而不会接收任何内容。实际上,我什至不确定该方法是否有效,但是即使有效,使用WaterfallStepContext::NextAsync()
API来推进瀑布也更为“正确”。看一下第三步对初学者的以下更改:
AddStep(async (stepContext, cancellationToken) => //ERROR
{
var nearOrSomewhereElse = stepContext.Result as FoundChoice;
var state = await (stepContext.Context.TurnState["FPBotAccessors"] as FPBotAccessors).FPBotStateAccessor.GetAsync(stepContext.Context);
state.NearOrSomewhereElse = nearOrSomewhereElse.Value;
if (state.NearOrSomewhereElse == "Somewhere else")
{
await stepContext.PromptAsync("textPrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply("Which location are you considering?")
});
}
else
{
await stepContext.NextAsync();
}
});
好的,现在这是您需要对以下步骤进行的更改:
AddStep(async (stepContext, cancellationToken) =>
{
var nearOrSomewhereElse = await (stepContext.Context.TurnState["FPBotAccessors"] as FPBotAccessors).FPBotStateAccessor.GetAsync(stepContext.Context).NearOrSomewhereElse;
// If it's somewhere else, then this step need to get the text value the person was prompted for in the previous step
if(nearOrSomewhereElse.Value == "Somewhere else")
{
// Get the result of the text prompt from the previous step
var whereExactly = stepContext.Result as string;
// TODO: store the value in your state so you can reference it later in the final search
}
return await stepContext.PromptAsync("choicePrompt",
new PromptOptions
{
Prompt = stepContext.Context.Activity.CreateReply($"Please indicate the size of {state.RealEstateType}"),
Choices = new[] {new Choice {Value = "Size 1"},
new Choice {Value = "Size 2"},
new Choice {Value = "Size 3"}
}.ToList()
});
});
我还应该指出,有 MUCH 个更简洁的方法可以完全不使用状态访问器来执行此操作。您实际上应该将在瀑布流中收集的中间值存储到WaterfallStepContext::Values
属性中。