microsoft / botframework-sdk

Bot Framework provides the most comprehensive experience for building conversation applications.
MIT License
7.5k stars 2.44k forks source link

Exception thrown: 'System.Runtime.Serialization.SerializationException' in mscorlib.dll #721

Closed secondubly closed 8 years ago

secondubly commented 8 years ago

Essentially what the title says, in my MessageReceivedAsync method, I grab the user's message and make a HTTP call to Luis to grab the relevant intents that match it - if it matches a specific one, I route to a specific part of the conversation. My problem is that on the first pass, the routing works fine, but on the second pass, in a specific if-statement, I get a serialization exception - which doesn't makes sense because if it worked the first time, why wouldn't it work the second time? I've marked the relevant class as Serializable, but that's not solving the problem. My code is below:

MessageReceivedAsync

        public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
        {
            var message = await argument;
            logger.LogUserMessages(argument); //log the user's message

            message.Text.ToLower();
            //if user says hi (initiates conversation) - we should respond with the canned message
            if(message.Text.Contains("hello") || message.Text.Contains("hi"))
            {
                string botResponse = "Hi, I'm your personal Dev Center Assistant! What can I help you with today?";
                await context.PostAsync(botResponse);
                logger.LogBotMessages(botResponse); //log bot's response
                context.Wait(MessageReceivedAsync);
            }
            //otherwise, they're trying to continue a conversation, so we should route accordingly
            else
            {
                //check which intent the user's message matches
                InitialIntentLUIS messageIntents = await InitialIntentLUIS.GetInitialIntentEntityFromLUIS(message.Text);
                var response = messageIntents.intents;
                logger.LogBotIntents(messageIntents.intents);
                //if they're asking to find an app, grab their seller ID
                **if(messageIntents.intents[0].intent == "AppNotFound")
                {
                    PromptDialog.Text(context, GetSellerIdAsync, "It looks like you're looking for an app - great! To facilitate this, I'll need your seller ID.");
                }**
                else if(response[0].intent == "Help")
                {

                }
            }
        }

InitialIntentLUIS

{
    [Serializable]
    public class InitialIntentLUIS
    {
        public string query { get; set; }
        public Intent[] intents { get; set; }
        public Entity[] entities { get; set; }
        public static async Task<InitialIntentLUIS> GetInitialIntentEntityFromLUIS(string Query)
        {
            Query = Uri.EscapeDataString(Query);
            InitialIntentLUIS Data = new InitialIntentLUIS();
            using (HttpClient client = new HttpClient())
            {
                string RequestURI = "https://api.projectoxford.ai/luis/v1/application?id=1c1094a6-8116-4086-a36e-2c53c8196f0f&subscription-key=de890c10834a48518581d3b4bf3e393c&q=" + Query;
                HttpResponseMessage msg = await client.GetAsync(RequestURI);

                if (msg.IsSuccessStatusCode)
                {
                    var JsonDataResponse = await msg.Content.ReadAsStringAsync();
                    Data = JsonConvert.DeserializeObject<InitialIntentLUIS>(JsonDataResponse);
                }
            }
            return Data;
        }
    }
    [Serializable]
    public class Intent
    {
        public string intent { get; set; }
        public float score { get; set; }
    }
    [Serializable]
    public class Entity
    {
        public string entity { get; set; }
        public string type { get; set; }
        public int startIndex { get; set; }
        public int endIndex { get; set; }
        public float score { get; set; }
    }
}

I double-starred the if-statement that is causing trouble - again, it works when the user goes through the first pass (telling the bot that they're looking for an app) but when they respond to that message (provide their seller ID) the bot throws a serialization error.

Any help would be greatly appreciated!

garypretty commented 8 years ago

Hi @epitone.

I'm afraid I can't see your specific problem, but (and sorry if I am telling you something you already know but, even if you do, maybe it can help someone else). There is a specific Dialog to help with using the LUIS service. The LUISDialog (https://docs.botframework.com/en-us/csharp/builder/sdkreference/d8/df9/class_microsoft_1_1_bot_1_1_builder_1_1_dialogs_1_1_luis_dialog.html) allows you to decorate it with properties to point to your specific model and then you can have a method per Intent (as well as a method for when an intent is not matched).

I am working on a blog post about this, but it isn't finished yet, but there is a good one at http://mayoster.blogspot.co.uk/2016/05/luis-and-bot-framework-natural-language.html.

secondubly commented 8 years ago

thanks @garypretty ! I may just switch to this method, as my current method is proving to be quite frustrating. I'm going to go ahead and close this.

Though when you finish that blog post, I'd love to see it!

garypretty commented 8 years ago

Great, well follow me on Twitter (@garypretty) or keep an eye on www.garypretty.co.uk - it should be up in a few days! Let me know how you get on with the LUISDialog too.