Bot Userstate пуст при загрузке - PullRequest
0 голосов
/ 17 июня 2019

Я использую Microsoft Bot Framework v4.4.5, и при запуске бота в эмуляторе Azure / localhost кажется, что UserState, хранящийся в хранилище больших двоичных объектов, пуст в файле turncontext / bot.Объект состояния содержит только данные по умолчанию, т. Е. Строки пусты.

При использовании памяти все отлично работает, а данные состояния хранятся в памяти и содержат правильные значения.

В OnMembersAddedAsync _userState.SaveChangesAsync сохраняет правильное состояние в хранилище больших двоичных объектов.

Получение клиента в OnTurnAsync всегда возвращает значение по умолчанию ClientProfile.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
        {
            // Error handling
            services.AddSingleton<IBotFrameworkHttpAdapter, BotErrorAdapter>();

            const string storageContainer = "#Name#";
            IStorage dataStore = new AzureBlobStorage("#ConnectionString#", storageContainer);

            // Bot registration
            services.AddBot<Bot>(options =>
            {
                options.CredentialProvider = new ConfigurationCredentialProvider(_configuration);
            });

            services.AddHttpClient();

            var conversationState = new ConversationState(dataStore);
            var userState = new UserState(dataStore);

            services.AddSingleton(conversationState);
            services.AddSingleton(userState);

            services.AddSingleton(_configuration);
        }

Bot.cs: ​​

        private IStorage _storage;
        private BotState _userState;

        public QnaBot(UserState userState, IStorage storage)
        {            
            _userState = userState;
            _storage = storage;
        }

        public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = new CancellationToken())
        {
            await base.OnTurnAsync(turnContext, cancellationToken);

            if (turnContext.Activity.Type is ActivityTypes.Message)
            {
                string userInput = turnContext.Activity.Text;

                // LoadAsync doesn't seem to set any data
                await _userState.LoadAsync(turnContext, false, cancellationToken);

                var userStateAccessors = _userState.CreateProperty<ClientProfile>(nameof(ClientProfile));
                var client = await userStateAccessors.GetAsync(turnContext, () => new ClientProfile());

                await turnContext.SendActivityAsync($"You wrote {userInput}, Session {client.Name}");

                await turnContext.SendActivityAsync($"Content {content}");
            }
        }

        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            var userStateAccessors = _userState.CreateProperty<ClientProfile>(nameof(ClientProfile));
            var client = await userStateAccessors.GetAsync(turnContext, () => new ClientProfile());

            if (!client.FetchedData)
            {
                client.Name = "MyName";
                client.FetchedData = true;

                await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
            }

            await turnContext.SendActivityAsync($"Hi my name is {client.Name}");
        }

ClientProfile.cs:

        public class ClientProfile
        {
            public string Name { get; set; }
        }

Может кто-нибудь сказать мне, что я здесь не так делаю?

1 Ответ

0 голосов
/ 18 июня 2019

Вам необходимо сохранить данные о состоянии и в другом методе. Так же, как вы упомянули, это делается в методе OnMembersAddedAsync (await _userState.SaveChangesAsync(turnContext, false, cancellationToken);), вы должны сделать это в методе OnTurnAsync.

В настоящее время загружаются данные userState:
await _userState.LoadAsync(turnContext, false, cancellationToken);

Но вам нужно сохранить его в конце метода:

await base.OnTurnAsync(turnContext, cancellationToken);

    if (turnContext.Activity.Type is ActivityTypes.Message)
    {
    string userInput = turnContext.Activity.Text;

                    // LoadAsync doesn't seem to set any data
                    await _userState.LoadAsync(turnContext, false, cancellationToken);

                    var userStateAccessors = _userState.CreateProperty<ClientProfile>(nameof(ClientProfile));
                    var client = await userStateAccessors.GetAsync(turnContext, () => new ClientProfile());

                    await turnContext.SendActivityAsync($"You wrote {userInput}, Session {client.Name}");

                    await turnContext.SendActivityAsync($"Content {content}");

                    //Add this line
                    await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
                }
...