2017-04-09 43 views
0

我正在與來自Microsoft的Bot Builder和LUIS一起玩耍,我對於非常基本的東西有些困難。調用FormDialog並立即啓動

我有簡單的方法來響應LUIS意圖,其中一個我想調用FormDialog(所以基於一個非常簡單的模型),就是這樣。當意圖被識別時,我正確地輸入了正確的方法,並且我也看到我的模型的BuildForm方法被調用,但是然後bot不會通過這些字段來詢問用戶的值。

這裏是我的意圖方法的代碼(代碼沒有做太多,它沒有真正的章節目標尚未):

[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意圖,但立即迴應「消息框配置!」,該消息應該在之後發送,用戶瀏覽表單。

有沒有人有關於我應該怎麼做的想法?

謝謝:)

+0

請出示您的形式,而且在context.Wait(的messageReceived)應該是別人的內部和形式的「ResumeAfter」法內。 –

+0

我將表單代碼添加到了原始文章中。我也移動了context.Wait(...)調用,現在我得到了我的表單的開頭(消息+第一個字段提示符),但立即出現錯誤:'異常:捕獲環境的匿名方法閉包不可序列化,請考慮刪除環境捕獲或使用反射序列化代理:BotTest.Dialogs.LUISDialog + <> c__DisplayClass4_0' – Jeahel

+0

正確,這是因爲異步(c,r)=>。將其移至某個方法並讓我知道。一旦你確認我可以制定答案。 –

回答

0

有跡象表明,你需要爲了解決這個問題,以改變兩兩件事:

  1. 移動else子句內部和形式的​​方法裏面context.Wait(MessageReceived)電話。這是必需的,因爲在調用錯誤的表單後,您正在等待的當前代碼。如果你打電話給一個對話框/表格,你不必等待
  2. 將​​方法作爲一個匿名函數可能會導致序列化問題,所以我建議您改爲創建一個方法。每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.

+0

謝謝你的解釋:-) – Jeahel

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意圖填寫了我班的一些字段,這就是爲什麼我在創建表單之前創建它。

相關問題