Exception in BOT Framework application in a FormBu

2019-09-18 13:24发布

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.

  1. First part is MessagesController class from where I call FlightManager which is a LUIS dialog.
  2. The second part of the code is FlightManager class from where I call FlightBooking class.
  3. 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();

        }
    }
}

1条回答
混吃等死
2楼-- · 2019-09-18 13:58

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:

public static IForm<FlightBooking> BuildForm()
{ //code   }

I hope this could help you, good luck with your bot!

查看更多
登录 后发表回答