调用 FormDialog 并立即启动它
Calling a FormDialog and starting it right away
我正在使用 Microsoft 的 Bot Builder 和 LUIS,但我在一些非常基本的东西上遇到了一些困难。
我有一些简单的方法来响应 LUIS 意图,在其中一个方法中,我想调用 FormDialog(因此基于我拥有的一个非常简单的模型),仅此而已。当意图被识别时,我正确地输入了正确的方法,我还看到我的模型的 BuildForm 方法被调用,但是机器人没有通过字段来询问用户值。
这是我的意图方法的代码(代码没有做太多,还没有真正的目的):
[LuisIntent("SendMessage")]
public async Task SendMessage(IDialogContext context, LuisResult result)
{
// Check if the user has already configured its message box
bool isBoxConfigured = false;
context.UserData.TryGetValue<bool>(Constants.UserData.IsBoxConfigured, out isBoxConfigured);
if (!isBoxConfigured)
{
// Configure box
context.Call(new FormDialog<MessageBox>(new MessageBox(), this._configureMessageBox, FormOptions.PromptInStart), async (c, r) =>
{
await c.PostAsync("Message Box configurée !");
});
}
else
{
// Send message
await context.PostAsync("Votre Message Box est déjà configurée. Le message a été envoyé !");
}
context.Wait(MessageReceived);
}
这是我的 LUIS 对话框的构造函数和 _configureMessageBox
属性 class:
public readonly BuildFormDelegate<MessageBox> _configureMessageBox;
public LUISDialog(BuildFormDelegate<MessageBox> configureMessageBox)
{
_configureMessageBox = configureMessageBox;
}
这是我的模型(表格):
[Serializable]
public class MessageBox
{
[Describe("numéro d'identification")]
[Prompt("Quel est le {&} de votre Message Box ?")]
public int Id { get; set; }
[Describe("surnom")]
[Prompt("Quel {&} voulez-vous lui donner ?")]
public string BoxName { get; set; }
public static IForm<MessageBox> BuildForm()
{
return new FormBuilder<MessageBox>()
.Message("Mmmh... Je ne connais pas votre Message Box. J'ai besoin de quelques informations.")
.Build();
}
}
当我向机器人发送消息 "envoie un message" 时,它识别出 SendMessage
意图,但立即响应 "Message Box configurée !",这应该在 之后发送 用户填写表格。
有人知道我应该怎么做吗?
谢谢:)
我遇到了同样的问题,尽管当我将 FormOptions.PromptInStart
添加到我的代码时,表单立即启动。这是我的代码和表格。
来自 LUIS 意图的调用:
var searchForm = new SearchForm();
var form = new FormDialog<SearchForm>(searchForm, SearchForm.BuildTestForm, FormOptions.PromptInStart);
context.Call(form, async (dialogContext, awaitable) =>
{
var r = await awaitable;
//handle result.
});
搜索表单class:
public static IForm<SearchForm> BuildTestForm()
{
return new FormBuilder<SearchForm>()
.Message("Start of form message.")
.Field(...)
...
.Build()
}
希望对您有所帮助。
PS:我的 LUIS 意图填充了我 class 中的一些字段,这就是我在创建表单之前创建它的原因。
为了解决这个问题,您需要更改两件事:
- 将
context.Wait(MessageReceived)
调用移到 else 子句和表单的 ResumeAfter<T>
方法中。这是必需的,因为使用您当前的代码,您在调用错误的表单后正在等待。如果您致电 dialog/form,则无需等待
- 将
ResumeAfter<T>
方法作为匿名函数可能会导致序列化问题,因此我建议改为创建一个方法。根据 docs:
Ensure that all dialogs are serializable.
This can be as simple as using the [Serializable] attribute on your IDialog implementations. But beware that anonymous method closures are not serializable if they reference their outside environment to capture variables. We also support a reflection-based serialization surrogate to help serialize types not marked as serializable.
我正在使用 Microsoft 的 Bot Builder 和 LUIS,但我在一些非常基本的东西上遇到了一些困难。
我有一些简单的方法来响应 LUIS 意图,在其中一个方法中,我想调用 FormDialog(因此基于我拥有的一个非常简单的模型),仅此而已。当意图被识别时,我正确地输入了正确的方法,我还看到我的模型的 BuildForm 方法被调用,但是机器人没有通过字段来询问用户值。
这是我的意图方法的代码(代码没有做太多,还没有真正的目的):
[LuisIntent("SendMessage")]
public async Task SendMessage(IDialogContext context, LuisResult result)
{
// Check if the user has already configured its message box
bool isBoxConfigured = false;
context.UserData.TryGetValue<bool>(Constants.UserData.IsBoxConfigured, out isBoxConfigured);
if (!isBoxConfigured)
{
// Configure box
context.Call(new FormDialog<MessageBox>(new MessageBox(), this._configureMessageBox, FormOptions.PromptInStart), async (c, r) =>
{
await c.PostAsync("Message Box configurée !");
});
}
else
{
// Send message
await context.PostAsync("Votre Message Box est déjà configurée. Le message a été envoyé !");
}
context.Wait(MessageReceived);
}
这是我的 LUIS 对话框的构造函数和 _configureMessageBox
属性 class:
public readonly BuildFormDelegate<MessageBox> _configureMessageBox;
public LUISDialog(BuildFormDelegate<MessageBox> configureMessageBox)
{
_configureMessageBox = configureMessageBox;
}
这是我的模型(表格):
[Serializable]
public class MessageBox
{
[Describe("numéro d'identification")]
[Prompt("Quel est le {&} de votre Message Box ?")]
public int Id { get; set; }
[Describe("surnom")]
[Prompt("Quel {&} voulez-vous lui donner ?")]
public string BoxName { get; set; }
public static IForm<MessageBox> BuildForm()
{
return new FormBuilder<MessageBox>()
.Message("Mmmh... Je ne connais pas votre Message Box. J'ai besoin de quelques informations.")
.Build();
}
}
当我向机器人发送消息 "envoie un message" 时,它识别出 SendMessage
意图,但立即响应 "Message Box configurée !",这应该在 之后发送 用户填写表格。
有人知道我应该怎么做吗?
谢谢:)
我遇到了同样的问题,尽管当我将 FormOptions.PromptInStart
添加到我的代码时,表单立即启动。这是我的代码和表格。
来自 LUIS 意图的调用:
var searchForm = new SearchForm();
var form = new FormDialog<SearchForm>(searchForm, SearchForm.BuildTestForm, FormOptions.PromptInStart);
context.Call(form, async (dialogContext, awaitable) =>
{
var r = await awaitable;
//handle result.
});
搜索表单class:
public static IForm<SearchForm> BuildTestForm()
{
return new FormBuilder<SearchForm>()
.Message("Start of form message.")
.Field(...)
...
.Build()
}
希望对您有所帮助。
PS:我的 LUIS 意图填充了我 class 中的一些字段,这就是我在创建表单之前创建它的原因。
为了解决这个问题,您需要更改两件事:
- 将
context.Wait(MessageReceived)
调用移到 else 子句和表单的ResumeAfter<T>
方法中。这是必需的,因为使用您当前的代码,您在调用错误的表单后正在等待。如果您致电 dialog/form,则无需等待 - 将
ResumeAfter<T>
方法作为匿名函数可能会导致序列化问题,因此我建议改为创建一个方法。根据 docs:Ensure that all dialogs are serializable. This can be as simple as using the [Serializable] attribute on your IDialog implementations. But beware that anonymous method closures are not serializable if they reference their outside environment to capture variables. We also support a reflection-based serialization surrogate to help serialize types not marked as serializable.