I am getting below error in FormFlow. A quick help is really appreciable.
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)
After searching on StackOverflow and GitHub I got a piece of a code which says that "You need to register it in autofac container".
So I placed below code in WebAPIConfig.cs
var builder = new ContainerBuilder();
builder.RegisterModule(new ReflectionSurrogateModule());
builder.Update(Conversation.Container);
But still I got an error, but this time error was different compared to previous and it is given below,
"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
I have copied the complete code of my application over here.
- First part is MessagesController class from where I call FlightManager which is a LUIS dialog.
- The second part of the code is FlightManager class from where I call FlightBooking class.
Third is actual flight booking 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();
}
}
}
I have had the first exception and from what I have learned, you cannot send parameters when you call the form builder method in this line:
BuildFormDelegate<FlightBooking> MakeFlightBookingForm = () => FlightBooking.BuildForm(context);
So make sure you declare the method without any parameters:
I hope this could help you, good luck with your bot!