Botframework 调用FormDialog并立即启动它

Botframework 调用FormDialog并立即启动它,botframework,azure-language-understanding,Botframework,Azure Language Understanding,我正在和微软的Bot Builder和LUIS一起玩,我在做一些基本的东西时遇到了一些困难 我有一些简单的方法来响应LUIS的意图,在其中一个方法中,我想调用一个FormDialog(基于我拥有的一个非常简单的模型),就是这样。当识别出意图时,我正确地输入了正确的方法,并且我还看到调用了我的模型的BuildForm方法,但是bot没有通过字段向用户询问值 下面是我的intent方法的代码(代码做的不多,它还没有真正的pupose): [LuisIntent(“发送消息”)] 公共异步任务Send

我正在和微软的Bot Builder和LUIS一起玩,我在做一些基本的东西时遇到了一些困难

我有一些简单的方法来响应LUIS的意图,在其中一个方法中,我想调用一个FormDialog(基于我拥有的一个非常简单的模型),就是这样。当识别出意图时,我正确地输入了正确的方法,并且我还看到调用了我的模型的BuildForm方法,但是bot没有通过字段向用户询问值

下面是我的intent方法的代码(代码做的不多,它还没有真正的pupose):

[LuisIntent(“发送消息”)]
公共异步任务SendMessage(IDialogContext上下文,LuisResult结果)
{
//检查用户是否已配置其消息框
bool isBoxConfigured=false;
context.UserData.TryGetValue(Constants.UserData.IsBoxConfigured,out-IsBoxConfigured);
如果(!isboxConfiguration)
{
//配置框
调用(新建FormDialog(newMessageBox(),this.\u configureMessageBox,FormOptions.PrompInstart),异步(c,r)=>
{
等待c.PostAsync(“消息框配置!”);
});
}
其他的
{
//发送消息
wait context.PostAsync(“Votre消息框est déjéa configureée.Le Message aétéemissioné!”);
}
Wait(MessageReceived);
}
以下是我的LUIS对话框类的构造函数和
\u configureMessageBox
属性:

public readonly BuildFormDelegate\u configureMessageBox;
公共LUISDialog(BuildFormDelegate配置消息框)
{
_configureMessageBox=configureMessageBox;
}
这是我的模型(表格):

[可序列化]
公共类消息框
{
[描述(“身份号码”)]
[提示(“Quel est le{&}de votre消息框?”)]
公共int Id{get;set;}
[描述(“surnom”)]
[提示(“请问您是路易·唐纳吗?”)]
公共字符串BoxName{get;set;}
公共静态表单BuildForm()
{
返回新的FormBuilder()
.Message(“Mmmh…Je ne connais pas votre Message Box.J'ai besoin de quelqueques informations.”)
.Build();
}
}
当我向bot发送消息“envoie un message”时,它会识别
SendMessage
意图,但会立即响应“message Box configureée!”,这应该在用户浏览表单后发送

有人知道我该怎么做吗


谢谢:)

我也遇到了同样的问题,尽管我在代码中添加了
FormOptions.PromptInStart
,表单立即启动。这是我的代码和表格

LUIS intent的电话:

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.
});
var searchForm=newsearchform();
var form=new FormDialog(searchForm、searchForm.BuildTestForm、FormOptions.prompinstart);
调用(表单,异步(dialogContext,等待)=>
{
var r=等待等待;
//处理结果。
});
SearchForm类:

public static IForm<SearchForm> BuildTestForm()
{
     return new FormBuilder<SearchForm>()
         .Message("Start of form message.")
         .Field(...)
         ...
         .Build()
}
publicstaticiformbuildtestform()
{
返回新的FormBuilder()
.Message(“表单开始消息”)
.字段(…)
...
.Build()
}
我希望这有帮助


PS:我的LUIS intent填充了我的类中的一些字段,这就是为什么我在创建表单之前创建它。

要解决此问题,您需要更改两件事:

  • context.Wait(MessageReceived)
    调用移动到表单的else子句和
    resumeafth
    方法中。这是必需的,因为使用当前代码,您在调用错误的表单后正在等待。如果调用对话框/窗体,则无需等待
  • ResumeAfter
    方法作为匿名函数会导致序列化问题,因此我建议改为创建一个方法。根据: 确保所有对话框都可序列化。 这可以像在IDialog实现中使用[Serializable]属性一样简单但请注意,如果匿名方法闭包引用其外部环境来捕获变量,则它们是不可序列化的。我们还支持基于反射的序列化代理,以帮助序列化未标记为可序列化的类型


  • 请出示您的表单以及上下文。Wait(MessageReceived)应该位于表单的else和ResumeAfter方法中。我已将表单代码添加到我的原始帖子中。我还移动了
    context.Wait(…)
    调用,正如您所说,现在我得到了表单的开头(消息+第一个字段提示符),但紧接着我得到了一个错误:
    Exception:捕获环境的匿名方法闭包不可序列化,考虑删除环境捕获或使用反射序列化代理:BoTest.diux.LuSudioC+CysDePase4Ly0<0/Cord>右,这是因为异步(C,R)= >。移动到一个方法,让我知道。一旦你确认了,我就能想出一个答案。太好了!现在可以了,谢谢!但是在整个dialog类中,回调似乎是非常必要的。这似乎不太实际。这是一个好的做法吗?我只是补充了正式的答案。请投票并标记为已回答。您可以使用匿名方法,但您需要确保它们可序列化,否则它将失败并出现错误。更多细节请参见我的答案。感谢您的解释:-)