【发布时间】:2019-10-04 10:37:27
【问题描述】:
我正在使用 Bot framework V4.3,我一直在瀑布对话框中使用自适应卡,以获取用户信息,一旦用户单击提交按钮,我想获取值,并且我想返回上一步如果用户点击返回按钮。
这是我的自适应卡片的样子
我已经尝试了@mdrichardson 在Stack Overflow 中给出的解决方案 但是自适应卡又重新提示了。
下面的代码帮助我们回到上一步,但是如何实现它到自适应卡片的后退按钮。
stepContext.ActiveDialog.State["stepIndex"] =(int)stepContext.ActiveDialog.State["stepIndex"] - 2;
在对话框中添加自适应卡片。 我什至用过 TextPrompt 而不是 ChoicePrompt
AddDialog(new ChoicePrompt("AdaptiveCardPrompt") { Style = ListStyle.None });
这就是我显示自适应卡片的方式。我的自适应卡是 Json 格式
cardAttachment = CreateAdaptiveCardAttachment();
return await stepContext.PromptAsync("AdaptiveCardPrompt",
new PromptOptions
{
Prompt = (Activity)MessageFactory.Attachment(new Attachment
{
ContentType = AdaptiveCard.ContentType,
Content = cardAttachment.Content
}),
}, cancellationToken);
请帮助我解决这个问题。提前谢谢你
从 Botframework 支持编辑:请不要使用下面的代码块。它仅适用于模拟器。相反,使用:
if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
activity.Text = JsonConvert.SerializeObject(activity.Value);
}
编辑 1:@mdrichardson 这是我设置对话框调用的方式
public static async Task Run(this Dialog dialog, ITurnContext turnContext,IStatePropertyAccessor<DialogState> accessor, CancellationToken cancellationToken = default(CancellationToken))
{
var dialogSet = new DialogSet(accessor);
dialogSet.Add(dialog);
var dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken);
// Ensure that message is a postBack (like a submission from Adaptive Cards)
if (dialogContext.Context.Activity.GetType().GetProperty("ChannelData") != null)
{
var channelData = JObject.Parse(dialogContext.Context.Activity.ChannelData.ToString());
if (channelData.ContainsKey("postBack"))
{
var postbackActivity = dialogContext.Context.Activity;
// Convert the user's Adaptive Card input into the input of a Text Prompt
// Must be sent as a string
postbackActivity.Text = postbackActivity.Value.ToString();
await dialogContext.Context.SendActivityAsync(postbackActivity);
}
}
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
if (results.Status == DialogTurnStatus.Empty)
{
await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken);
}
}
在OnTurnAsync方法中
if (turnContext.Activity.Type == ActivityTypes.Message)
{
await Dialog.Run(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
编辑 2 :我修改了代码,我能够进入下一个瀑布步骤。但我在这里面临另一个问题。 没有显示下一个提示,但我可以在日志中看到它 这是它在模拟器中的显示方式
一旦用户点击按钮,控件就会进入MoreInfoAsync方法
private async Task<DialogTurnResult> MoreInfoAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var goback = JObject.Parse(stepContext.Result.ToString());
stepContext.Values["AdaptiveCardDetails"] = stepContext.Result.ToString();
if (goback.ContainsKey("goBack"))
{
return await stepContext.ReplaceDialogAsync(InitialDialogId);
}
// stepContext.ActiveDialog.State["stepIndex"] = (int)stepContext.ActiveDialog.State["stepIndex"] - 2;
else
return await stepContext.PromptAsync("MoreInfo", new PromptOptions { Prompt = MessageFactory.Text("Tell Me more.") }, cancellationToken);
}
我想进入初始对话框,所以我使用ReplaceDialogAsync。
MoreInfo 对话框不显示在模拟器中,但显示在日志中
编辑3:这里是瀑布步骤的完整代码
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[]
{
ChoiceAsync,
CardAsync,
MoreInfoAsync,
ConfirmAsync
};
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
AddDialog(new ChoicePrompt("ChoiceType"));
AddDialog(new TextPrompt("AdaptiveCardPrompt"));
AddDialog(new TextPrompt("MoreInfo"));
InitialDialogId = nameof(WaterfallDialog);
private async Task<DialogTurnResult> ChoiceAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
options = new PromptOptions()
{
Prompt = MessageFactory.Text("Select the Choice"),
RetryPrompt = MessageFactory.Text("That was not a valid choice."),
Choices = GetChoices(),
Style = ListStyle.HeroCard
};
return await stepContext.PromptAsync("ChoiceType", options, cancellationToken);
}
private async Task<DialogTurnResult> CardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var cardAttachment = new Attachment();
stepContext.Values["leaveType"] = stepContext.Result.ToString();
cardAttachment = CreateAdaptiveCardAttachment();
return await stepContext.PromptAsync("AdaptiveCardPrompt",
new PromptOptions
{
Prompt = (Activity)MessageFactory.Attachment(new Attachment
{
ContentType = AdaptiveCard.ContentType,
Content = cardAttachment.Content,
}),
}, cancellationToken);
}
private async Task<DialogTurnResult> MoreInfoAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var goback = JObject.Parse(stepContext.Result.ToString());
stepContext.Values["AdaptiveCardDetails"] = stepContext.Result.ToString();
if (goback.ContainsKey("goBack"))
{
return await stepContext.ReplaceDialogAsync(InitialDialogId);
}
else return await stepContext.PromptAsync("MoreInfo", new PromptOptions { Prompt = MessageFactory.Text("Tell Me more.") }, cancellationToken);
}
private async Task<DialogTurnResult> ConfirmAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["MoreInfo"] = stepContext.Result;
//As of now I wouldn't perform any task here so I'll end
return await stepContext.EndDialogAsync();
}
【问题讨论】:
-
如果卡片再次显示,这可能与您设置对话框的方式有关,而不是卡片的发送方式。您可以包含对话框的代码吗?要返回,在“捕获结果”步骤中,您只需要查看
stepContext.Result是否具有您的go back值(无论您设置卡片在点击返回时发送的任何值) -
使用
ReplaceDialogAsync是个好主意,而且您使用正确。很难说为什么它没有被展示。您可以粘贴MoreInfo对话框的所有代码或指向您的存储库的链接吗?您能否再描述一下您的新问题?只是对话框没有重新启动吗? -
我已经粘贴了
MoreInfo对话框的完整代码,如果您在提交提交按钮后看到模拟器快照,则控件转到MoreInfo,但在Moreinfo中,我试图返回的提示没有得到显示在模拟器输出屏幕中。但是我可以在模拟器日志中看到“告诉我更多信息”。为什么在输出时向用户显示的不一样。我哪里做错了 -
很难说。
MoreInfoAsync看起来不错,所以问题可能出在其他地方。你有类似AddDialog(new TextPrompt("MoreInfo"));的东西吗?如果您可以链接到所有代码,这将使调试变得更加容易。 -
我无法复制这个。问题可能出在
Run()中的await dialogContext.Context.SendActivityAsync(postbackActivity);。尝试删除它,因为您实际上并不需要发送它。我已经上传了我的代码to a github repo,所以你可以看看并尝试找出不同之处。同样,使用您的所有代码进行调试会更加容易。
标签: botframework