[英]MS Bot builder IForm Invalid Type Exception:Has xxx Expect yyy
I'm trying to build a Simple iForm Based bot. 我正在尝试构建一个基于iForm的简单bot。 When one Form is completed I want to show another. 一张表格填写完毕后,我想显示另一张表格。 Both Forms consist of a single enum value. 两种形式都包含一个枚举值。 The first form show correctly. 第一种形式显示正确。 When I select a option, the SelectNextAction
is called as expected. 当我选择一个选项时,将按预期方式调用SelectNextAction
。 The first dialog is constructed via: 通过以下方式构造第一个对话框:
public static IForm<RootForm> BuildRootForm()
{
IForm<RootForm> ret = new FormBuilder<RootForm>()
.Message("Hi")
.AddRemainingFields()
.OnCompletion(SelectNextAction)
.Build();
return ret;
}
private static async Task SelectNextAction(IDialogContext context, RootForm state)
{
// Tell the user that the form is complete
switch (state.Choice)
{
case MainChoice.Transfer:
IFormDialog<TransferForm> form = FormDialog.FromForm(TransferForm.BuildTransferForm);
context.Call(form, TransferDialogComplete);
break;
default:
break;
}
}
After this code has run TransferDialogComplete
is called: 此代码运行后, TransferDialogComplete
调用TransferDialogComplete
:
private async static Task TransferDialogComplete(IDialogContext context, IAwaitable<TransferForm> result)
{
await result;
}
And then a Exception is thrown: 然后抛出一个异常:
Exception: invalid type: expected EBBot.Dialogs.TransferForm, have RootForm [File of type 'text/plain'] 异常:无效的类型:预期的EBBot.Dialogs.TransferForm,具有RootForm ['text / plain'类型的文件]
What am I doing wrong? 我究竟做错了什么? any idea or suggestions? 有什么想法或建议吗?
The delegate passed into the OnCompletion
method can not be used to call another forms or any other dialogs. 传递给OnCompletion
方法的委托不能用于调用其他表单或任何其他对话框。
This should only be used for side effects such as calling your service wit the form state results. 这仅应用于副作用,例如以表单状态结果调用服务。 In any case the completed form state will be passed to the parent dialog. 无论如何,完成的表单状态将传递到父对话框。
For an example look here . 例如看这里 。
How you can implement this is through the ResumeAfter
method. 您如何通过ResumeAfter
方法实现此目的。 Here is an example: 这是一个例子:
[Serializable]
public class RootDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
var form = new FormDialog<SimpleForm>(new SimpleForm1(),
SimpleForm1.BuildForm);
context.Call(form, ResumeAfterForm1);
}
private async Task ResumeAfterForm1(IDialogContext context, IAwaitable<object> result)
{
var form = new FormDialog<SimpleForm2>(new SimpleForm2(),
SimpleForm2.BuildForm, FormOptions.PromptInStart);
context.Call(form, ResumeAfterForm2);
}
// other code
}
Note : I used the PromptInStart
Because I have noticed that if you don't include this the form will not start right away. 注意 :我使用了PromptInStart
因为我已经注意到,如果您不包括该表单,它将不会立即启动。
As I mentioned in the comments, the issue is due to the call of the second form in the OnCompletion
call. 正如我在评论中提到的那样,该问题是由于在OnCompletion
调用中调用了第二种形式。
In order to solve this, you should call the second form in the ResumeAfter<T
> method that you specified when you call your first form. 为了解决这个问题,您应该在调用第一个表单时指定的ResumeAfter<T
>方法中调用第二个表单。
var rootForm = FormDialog.FromForm(RootForm.BuildRootForm);
context.Call(rootForm, AfterRootFormCompleted);
private async Task AfterRootFormCompleted(IDialogContext context, IAwaitable<RootForm> result)
{
try
{
var state = await result;
IFormDialog<TransferForm> form = FormDialog.FromForm(TransferForm.BuildTransferForm);
context.Call(form, TransferDialogComplete);
}
catch (FormCancelledException)
{
// do something;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.