调用FormDialog并立即启动它

时间:2017-04-09 11:02:30

标签: botframework luis

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

我有简单的方法来响应LUIS意图,其中一个我想调用一个FormDialog(所以我基​​于一个非常简单的模型),就是这样。当识别出intent时,我正确地输入了正确的方法,并且我也看到我的模型的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属性:

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意图,但立即响应“消息框配置!”,该消息应该在之后发送 >用户浏览表单。

有没有人知道我应该怎么做?

谢谢:)

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,但是当我将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.
});

SearchForm类:

public static IForm<SearchForm> BuildTestForm()
{
     return new FormBuilder<SearchForm>()
         .Message("Start of form message.")
         .Field(...)
         ...
         .Build()
}

我希望这会有所帮助。

PS:我的LUIS意图填写了我班级的一些字段,这就是我在创建表单之前创建它的原因。

答案 1 :(得分:0)

为了解决这个问题,您需要更改两件事:

  1. context.Wait(MessageReceived)调用移到else子句内和表单的ResumeAfter<T>方法内。这是必需的,因为在调用错误的表单后,您正在等待当前的代码。如果你打电话给对话/表格,你就不必等待
  2. ResumeAfter<T>方法作为匿名函数可能导致序列化问题,因此我建议您创建一个方法。根据{{​​3}}:
      

    确保所有对话框都可序列化。   这可以像在IDialog实现上使用[Serializable]属性一样简单。 但要注意,如果匿名方法闭包引用其外部环境来捕获变量,则它们不可序列化。我们还支持基于反射的序列化代理,以帮助序列化未标记为可序列化的类型。