将消息从自定义提示转发到另一个对话框
Forward message to another dialog from custom prompt
我正在使用 this 自定义 class 来制作自定义提示。
我修改了 tryParse 方法。如果用户不选择任何选项,我想将消息转发到第一个对话框。
代码:
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptios(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
我正在尝试覆盖 CancelablePromptOptions 中的 TryParse 函数 class :
protected override bool TryParse(IMessageActivity message, out T result)
{
if (IsCancel(message.Text))
{
result = default(T);
return true;
}
bool b = base.TryParse(message, out result);
if (!b)
Conversation.SendAsync(message, () => new MyFirstDialog());
return base.TryParse(message, out result);
}
注意代码中的 MyFirstDialog。我想用当前消息重新创建第一个对话框。
目标:如果用户选择了一些存储更多选项的对话框,并且如果第一个 "choose" 无效,我想重新创建 MyFirstDialog。
有什么想法吗?
编辑:
MyFirstDialog 是我从消息控制器调用的第一个 IDialog。
await Conversation.SendAsync(activity, () => new MyFirstDialog());
我正在从 MyFirstDialog 调用当前 IDialog:
context.Call(new CurrentDialog(), CurrentDialog.HandleOptions);
这里是一个关于如何返回初始对话的示例,从最低级别开始。
CancelablePromptChoice代码:
在这里你让基本实现做 "TryParse",但如果它不匹配你会处理它(通过 return 为真并保持值),避免重试
protected override bool TryParse(IMessageActivity message, out T result)
{
if (IsCancel(message.Text))
{
result = default(T);
return true;
}
var parsingTriedSucceeded = base.TryParse(message, out result);
// here you know if you found one of the options or not, and if not you override
if (!parsingTriedSucceeded)
{
result = (T)Convert.ChangeType(message.Text, typeof(T));
return true;
}
else
{
return parsingTriedSucceeded;
}
}
CurrentDialog代码:
在此代码中,您将在 OptionSelected 中处理您的默认 (T) 回复(这是在您的提示后恢复此对话框时调用的方法)。通过执行 context.Done<string>(null);
您将结束此对话框并返回 MyFirstDialog
[Serializable]
public class CurrentDialog : IDialog<string>
{
public async Task StartAsync(IDialogContext context)
{
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptions(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
}
private async Task OptionSelected(IDialogContext context, IAwaitable<string> result)
{
var chose = await result;
string answer = chose.ToString();
switch (answer)
{
case HelpEnumerator.Agenda:
await EventHelper.GetEventAgenda(context);
context.Done<string>(null);
break;
case HelpEnumerator.Register:
context.Call(new RegistrationDialog(), RegistrationDialog.Resume);
context.Done<string>(null);
break;
case HelpEnumerator.Speakers:
await EventHelper.GetSpeakers(context);
context.Done<string>(null);
break;
case HelpEnumerator.Tickets:
await EventHelper.GetTickets(context);
context.Done<string>(null);
break;
default:
context.Done(answer);
break;
}
}
}
MyFirstDialog代码:
所以最后在您的 MyFirstDialog 中,您必须使用 resume 方法从 CurrentDialog 处理这个 return:
// Somewhere in your logic...
context.Call(new CurrentDialog(), ResumeAfterCurrentDialog);
// On your class:
private async Task ResumeAfterCurrentDialog(IDialogContext context, IAwaitable<string> result)
{
// You are entering here after "context.Done(...)" in the CurrentDialog. To know the "result" value, take a look at what in the OptionSelected in CurrentDialog => it can be null for the options of the list, or the value in "answer" if it's not one of the options
// So we only have to test if it's not null, and then send the message again to the bot by using the "context.Activity" value
var resultText = await result;
if (resultText != null)
{
// Send the message again. It's already the message stored in context.Activity ;)
IMessageActivity msg = (IMessageActivity)context.Activity;
await this.MessageReceivedAsync(context, new AwaitableFromItem<IMessageActivity>(msg));
}
}
我正在使用 this 自定义 class 来制作自定义提示。
我修改了 tryParse 方法。如果用户不选择任何选项,我想将消息转发到第一个对话框。
代码:
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptios(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
我正在尝试覆盖 CancelablePromptOptions 中的 TryParse 函数 class :
protected override bool TryParse(IMessageActivity message, out T result)
{
if (IsCancel(message.Text))
{
result = default(T);
return true;
}
bool b = base.TryParse(message, out result);
if (!b)
Conversation.SendAsync(message, () => new MyFirstDialog());
return base.TryParse(message, out result);
}
注意代码中的 MyFirstDialog。我想用当前消息重新创建第一个对话框。
目标:如果用户选择了一些存储更多选项的对话框,并且如果第一个 "choose" 无效,我想重新创建 MyFirstDialog。
有什么想法吗?
编辑:
MyFirstDialog 是我从消息控制器调用的第一个 IDialog。
await Conversation.SendAsync(activity, () => new MyFirstDialog());
我正在从 MyFirstDialog 调用当前 IDialog:
context.Call(new CurrentDialog(), CurrentDialog.HandleOptions);
这里是一个关于如何返回初始对话的示例,从最低级别开始。
CancelablePromptChoice代码:
在这里你让基本实现做 "TryParse",但如果它不匹配你会处理它(通过 return 为真并保持值),避免重试
protected override bool TryParse(IMessageActivity message, out T result)
{
if (IsCancel(message.Text))
{
result = default(T);
return true;
}
var parsingTriedSucceeded = base.TryParse(message, out result);
// here you know if you found one of the options or not, and if not you override
if (!parsingTriedSucceeded)
{
result = (T)Convert.ChangeType(message.Text, typeof(T));
return true;
}
else
{
return parsingTriedSucceeded;
}
}
CurrentDialog代码:
在此代码中,您将在 OptionSelected 中处理您的默认 (T) 回复(这是在您的提示后恢复此对话框时调用的方法)。通过执行 context.Done<string>(null);
您将结束此对话框并返回 MyFirstDialog
[Serializable]
public class CurrentDialog : IDialog<string>
{
public async Task StartAsync(IDialogContext context)
{
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptions(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
}
private async Task OptionSelected(IDialogContext context, IAwaitable<string> result)
{
var chose = await result;
string answer = chose.ToString();
switch (answer)
{
case HelpEnumerator.Agenda:
await EventHelper.GetEventAgenda(context);
context.Done<string>(null);
break;
case HelpEnumerator.Register:
context.Call(new RegistrationDialog(), RegistrationDialog.Resume);
context.Done<string>(null);
break;
case HelpEnumerator.Speakers:
await EventHelper.GetSpeakers(context);
context.Done<string>(null);
break;
case HelpEnumerator.Tickets:
await EventHelper.GetTickets(context);
context.Done<string>(null);
break;
default:
context.Done(answer);
break;
}
}
}
MyFirstDialog代码:
所以最后在您的 MyFirstDialog 中,您必须使用 resume 方法从 CurrentDialog 处理这个 return:
// Somewhere in your logic...
context.Call(new CurrentDialog(), ResumeAfterCurrentDialog);
// On your class:
private async Task ResumeAfterCurrentDialog(IDialogContext context, IAwaitable<string> result)
{
// You are entering here after "context.Done(...)" in the CurrentDialog. To know the "result" value, take a look at what in the OptionSelected in CurrentDialog => it can be null for the options of the list, or the value in "answer" if it's not one of the options
// So we only have to test if it's not null, and then send the message again to the bot by using the "context.Activity" value
var resultText = await result;
if (resultText != null)
{
// Send the message again. It's already the message stored in context.Activity ;)
IMessageActivity msg = (IMessageActivity)context.Activity;
await this.MessageReceivedAsync(context, new AwaitableFromItem<IMessageActivity>(msg));
}
}