FormBuilder 中 BOT Framework 应用程序中的异常:无法通过非托管序列化委托
Exception in BOT Framework application in a FormBuilder : Cannot serialize delegates over unmanaged
我在 FormFlow 中遇到以下错误。
快速帮助真的很可观。
Exception: anonymous method closures that capture the environment are
not serializable, consider removing environment capture or using a
reflection serialization surrogate:
FlightBot.FlightManager+<>c__DisplayClass2_0", "attachments": [
{
"contentType": "text/plain",
"content": " at Microsoft.Bot.Builder.Internals.Fibers.Serialization.ClosureCaptureErrorSurrogate.System.Runtime.Serialization.ISerializationSurrogate.GetObjectData(Object
obj, SerializationInfo info, StreamingContext context)
在 Whosebug 和 GitHub 上搜索后,我得到一段代码,上面写着 "You need to register it in autofac container"。
所以我把下面的代码放在 WebAPIConfig.cs
var builder = new ContainerBuilder();
builder.RegisterModule(new ReflectionSurrogateModule());
builder.Update(Conversation.Container);
但是我还是报了错,但是这次的报错和之前的不一样,下面给出了,
"Exception: Cannot serialize delegates over unmanaged function
pointers, dynamic methods or methods outside the delegate creator's
assembly.", "attachments": [
{
"contentType": "text/plain",
"content": " at System.MulticastDelegate.GetObjectData(SerializationInfo info,
StreamingContext context)\r\n at
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object
obj, ISurrogateSelector surrogateSelector, StreamingContext context,
SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter,
ObjectWriter objectWriter, SerializationBinder binder)\r\n
我已经把我的应用程序的完整代码复制到这里了。
- 第一部分是我调用的 MessagesController class
FlightManager 是一个 LUIS 对话框。
- 代码的第二部分是我调用的 FlightManager class
航班预订 class.
第三个是实际订的机票class.
[BotAuthentication]
public class MessagesController : ApiController
{
internal static IDialog<object> MakeRootDialog()
{
return Chain.From(() => new FlightManager());
}
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, MakeRootDialog);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
namespace FlightBot
{
[LuisModel("luis model key", "luis secret")]
[Serializable]
public class FlightManager : LuisDialog<object>
{
public async Task FlightBookingTask(IDialogContext context, LuisResult result)
{
PromptDialog.Confirm(
context: context,
resume: ResumeAndHandleConfirmAsync,
prompt: $"It seems you wish to book a flight. Do you wish to continue?",
retry: "I didn't understand. Please try again.");
}
private async Task ResumeAndHandleConfirmAsync(IDialogContext context, IAwaitable<bool> argument)
{
FlightBooking cb = new FlightBooking();
BuildFormDelegate<FlightBooking> MakeFlightBookingForm = () => FlightBooking.BuildForm(context);
var flightBooking = new FormDialog<FlightBooking>(cb, MakeFlightBookingForm, FormOptions.PromptInStart, null);
context.Call(flightBooking, FlightBookingComplete);
}
private async Task FlightBookingComplete(IDialogContext context, IAwaitable<FlightBooking> result)
{
context.Wait(MessageReceived);
}
}
}
namespace FlightBot
{
[Serializable]
public class FlightBooking
{
[Prompt("Enter source :")]
public string Source { get; set; }
[Prompt("Enter destination :")]
public string Destination { get; set; }
public static IForm<FlightBooking> BuildForm(IDialogContext context)
{
return new FormBuilder<FlightBooking>().Message("Tell me about flight details!")
.Field(nameof(Source))
.Field(nameof(Destination))
.Build();
}
}
}
我遇到了第一个异常,据我了解,在这一行中调用表单构建器方法时无法发送参数:
BuildFormDelegate<FlightBooking> MakeFlightBookingForm = () => FlightBooking.BuildForm(context);
因此请确保您声明的方法没有任何参数:
public static IForm<FlightBooking> BuildForm()
{ //code }
希望对你有所帮助,祝你的机器人好运!
我在 FormFlow 中遇到以下错误。 快速帮助真的很可观。
Exception: anonymous method closures that capture the environment are not serializable, consider removing environment capture or using a reflection serialization surrogate: FlightBot.FlightManager+<>c__DisplayClass2_0", "attachments": [ { "contentType": "text/plain", "content": " at Microsoft.Bot.Builder.Internals.Fibers.Serialization.ClosureCaptureErrorSurrogate.System.Runtime.Serialization.ISerializationSurrogate.GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
在 Whosebug 和 GitHub 上搜索后,我得到一段代码,上面写着 "You need to register it in autofac container"。
所以我把下面的代码放在 WebAPIConfig.cs
var builder = new ContainerBuilder();
builder.RegisterModule(new ReflectionSurrogateModule());
builder.Update(Conversation.Container);
但是我还是报了错,但是这次的报错和之前的不一样,下面给出了,
"Exception: Cannot serialize delegates over unmanaged function pointers, dynamic methods or methods outside the delegate creator's assembly.", "attachments": [ { "contentType": "text/plain", "content": " at System.MulticastDelegate.GetObjectData(SerializationInfo info, StreamingContext context)\r\n at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)\r\n
我已经把我的应用程序的完整代码复制到这里了。
- 第一部分是我调用的 MessagesController class FlightManager 是一个 LUIS 对话框。
- 代码的第二部分是我调用的 FlightManager class 航班预订 class.
第三个是实际订的机票class.
[BotAuthentication] public class MessagesController : ApiController { internal static IDialog<object> MakeRootDialog() { return Chain.From(() => new FlightManager()); } public async Task<HttpResponseMessage> Post([FromBody]Activity activity) { if (activity.Type == ActivityTypes.Message) { await Conversation.SendAsync(activity, MakeRootDialog); } else { HandleSystemMessage(activity); } var response = Request.CreateResponse(HttpStatusCode.OK); return response; } private Activity HandleSystemMessage(Activity message) { if (message.Type == ActivityTypes.DeleteUserData) { // Implement user deletion here // If we handle user deletion, return a real message } else if (message.Type == ActivityTypes.ConversationUpdate) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels } else if (message.Type == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (message.Type == ActivityTypes.Typing) { // Handle knowing tha the user is typing } else if (message.Type == ActivityTypes.Ping) { } return null; } }
namespace FlightBot
{
[LuisModel("luis model key", "luis secret")]
[Serializable]
public class FlightManager : LuisDialog<object>
{
public async Task FlightBookingTask(IDialogContext context, LuisResult result)
{
PromptDialog.Confirm(
context: context,
resume: ResumeAndHandleConfirmAsync,
prompt: $"It seems you wish to book a flight. Do you wish to continue?",
retry: "I didn't understand. Please try again.");
}
private async Task ResumeAndHandleConfirmAsync(IDialogContext context, IAwaitable<bool> argument)
{
FlightBooking cb = new FlightBooking();
BuildFormDelegate<FlightBooking> MakeFlightBookingForm = () => FlightBooking.BuildForm(context);
var flightBooking = new FormDialog<FlightBooking>(cb, MakeFlightBookingForm, FormOptions.PromptInStart, null);
context.Call(flightBooking, FlightBookingComplete);
}
private async Task FlightBookingComplete(IDialogContext context, IAwaitable<FlightBooking> result)
{
context.Wait(MessageReceived);
}
}
}
namespace FlightBot
{
[Serializable]
public class FlightBooking
{
[Prompt("Enter source :")]
public string Source { get; set; }
[Prompt("Enter destination :")]
public string Destination { get; set; }
public static IForm<FlightBooking> BuildForm(IDialogContext context)
{
return new FormBuilder<FlightBooking>().Message("Tell me about flight details!")
.Field(nameof(Source))
.Field(nameof(Destination))
.Build();
}
}
}
我遇到了第一个异常,据我了解,在这一行中调用表单构建器方法时无法发送参数:
BuildFormDelegate<FlightBooking> MakeFlightBookingForm = () => FlightBooking.BuildForm(context);
因此请确保您声明的方法没有任何参数:
public static IForm<FlightBooking> BuildForm()
{ //code }
希望对你有所帮助,祝你的机器人好运!