BotFramework 消息控制器通过反向通道设置变量

BotFramework Message Controller set variable via Backchannel

我正在尝试通过 Backchannel 接收一个整数 (1-4),然后将其交给第一个对话框。

我的消息控制器如下所示:

       private int option = 1;
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        if (activity.Type == ActivityTypes.Message)
        {
            try
            {

                var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
                Activity isTypingReply = activity.CreateReply();
                isTypingReply.Type = ActivityTypes.Typing;
                await connector.Conversations.ReplyToActivityAsync(isTypingReply);

                await Conversation.SendAsync(activity, () => new Dialogs.MenuDialog(option));


            }
            catch (Exception e)
            {
                //SendEmail(e);
            }
        }
        else
        {
            await HandleSystemMessage(activity);
        }
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

    private async Task 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)
        {

        }
        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)
        {
        }
        else if (message.Type == ActivityTypes.Event && message.Name == "option")
        {

           // var reply = message.CreateReply();
            //reply.Text = message.Value.ToString();
           // ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));
           // await connector.Conversations.ReplyToActivityAsync(reply);

            if (message.Value.ToString() == "1")
            {
                option = 1;

            }
            else if (message.Value.ToString() == "2")
            {
                option = 2;
            }
            else if (message.Value.ToString() == "3")
            {
                option = 3;
            }
            else if (message.Value.ToString() == "4")
            {
                option = 4;
            }
            else
            {
                option = 1;
            }

        }


        return;
    }

Backchannel 方法调用正确,选项值在函数末尾打印时设置。 但是当第一条消息到来时,机器人总是使用默认的“1”值。 之前可以用,现在不行了,我不明白为什么。

private int option = 1;

作用域为 MessageController,每次调用时都会刷新。您可以使用 PrivateConversationData 来保留事件和消息调用之间的 'option':

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        //retrieve the option value before processing the message
        string optionValue = string.Empty;
        using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
        {
            var botData = scope.Resolve<IBotData>();
            await botData.LoadAsync(CancellationToken.None);
            optionValue = botData.PrivateConversationData.GetValue<string>("option");
        }

        await Conversation.SendAsync(activity, () => new ParameterizedRootDialog(optionValue));

    }
    else if (activity.Type == ActivityTypes.Event)
    {
        var eventActivity = activity.AsEventActivity();
        if (string.Equals(eventActivity.Name, "option", StringComparison.InvariantCultureIgnoreCase))
        {
            //save the option into PrivateConversationData
            string optionValue = eventActivity.Value.ToString();
            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
            {
                var botData = scope.Resolve<IBotData>();
                await botData.LoadAsync(CancellationToken.None);
                botData.PrivateConversationData.SetValue("option", optionValue);
                await botData.FlushAsync(CancellationToken.None);
            }                    
        }
    }

    return Request.CreateResponse(HttpStatusCode.OK);
}

另请注意:使用此方法,无需将选项作为参数发送到对话框。您可以使用 IDialogContext.PrivateConversationData 从对话框本身中检索值。像这样:

var optionFromContext = context.PrivateConversationData.GetValue<string>("option");