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

我已经把我的应用程序的完整代码复制到这里了。

  1. 第一部分是我调用的 MessagesController class FlightManager 是一个 LUIS 对话框。
  2. 代码的第二部分是我调用的 FlightManager class 航班预订 class.
  3. 第三个是实际订的机票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   }

希望对你有所帮助,祝你的机器人好运!