加载时Bot用户状态为空

时间:2019-06-17 12:52:12

标签: c# azure .net-core botframework azure-storage-blobs

我正在使用Microsoft Bot Framework v4.4.5,并且在Azure /本地主机模拟器中运行bot时,似乎存储在blob存储中的UserState在turncontext / bot中为空。  状态对象仅包含默认数据,即字符串为空。

使用内存存储时,一切正常,状态数据存储在内存中并包含正确的值。

在OnMember⚓Async_userState中,SaveChangesAsync将正确的状态保存到Blob存储中。

在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 :(得分:0)

您还需要用其他方法保存状态数据。就像您提到的是在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);
                }