有没有办法让'new StateClient(botCred)将用户数据保存到使用自定义IBotDataStore的机器人

时间:2017-07-28 18:25:28

标签: botframework

我正在尝试在我的机器人上实现custom authentication,如this article的模式A中所述。 但是,我的WebApplication试图写入我的BotStateDataStore的数据没有被保留在它上面,因此当我尝试从机器人本身读取它时不可用。

关键点:

我刚刚在我的机器人的同一个解决方案上创建了一个新的asp.net Web应用程序,在de bot Web.Config上设置了相同的MicrosoftAppId和MicrosoftAppPassword,并在新的Controller上实现了以下方法,以便尝试坚持:

public class AuthenticationController : ApiController
{
    // GET: api/Authentication
    [HttpGet]
    public async Task<bool> Authorize(string token)
    {
        try
        {
            var appId = ConfigurationManager.AppSettings["MicrosoftAppId"];
            var password = ConfigurationManager.AppSettings["MicrosoftAppPassword"];

            var botCred = new MicrosoftAppCredentials(appId, password);

            var stateClient = new StateClient(botCred);

            BotData botData = new BotData(eTag: "*");

            //Suppose I've just called an internal service to get the profile of my user and got it's profile:
            //Let's save it in the botstate to make this information avalilable to the bot cause I'll need it there in order to choose different Dialogs withing the bot depending on the user's profile (Anonimous, Identificado, Advanced or Professional)
            botData.SetProperty<string>('Profile', "Identificado");

            var data = await stateClient.BotState.SetUserDataAsync("directline", "User1", botData);
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
}

问题在于,当我尝试在机器人内部获取“profile”值时,上面代码的despide正在执行而没有任何异常,如下面的代码中所示,

context.UserData.TryGetValue<string>(stateKey, out perfil)

返回null

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            var message = await result;

            try
            {
                context.UserData.SetValue<string>("Perfil", "XXXXXXXXX");

                string perfil;
                if (context.UserData.TryGetValue<string>(stateKey, out perfil))
                {
                    await context.PostAsync($"Olá, fulano o seu perfil é '{perfil}'");
                }
                else
                {
                    await context.PostAsync($"Olá, anônimo");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            if (message.Text == null || message.Text.Equals(GlobalResources.Back, StringComparison.InvariantCultureIgnoreCase))
            {   //Quando entra nesse diálogo a 1ª vez ou volta de um dialogo filho.
                var rootCard = GetCard();

                var reply = context.MakeMessage();
                reply.Attachments.Add(rootCard);

                await context.PostAsync(reply);
                context.Wait(MessageReceivedAsync);
            }
            else if (message.Text.Equals(GlobalResources.AboutToro, StringComparison.InvariantCultureIgnoreCase))
            {
                context.Call(new AboutToroDialog(), OnResumeToRootDialog);
            }
            else
            {
                var messageToForward = await result;
                await context.Forward(new QnADialog(), AfterFAQDialog, messageToForward, CancellationToken.None);
                return;
            }
        }

任何人都可以请告诉我如何在我的bot的botStateStore中从asp.net web MVC应用程序中写一些值,这是另一个botframework(Asp.Net.WebApi)应用程序吗?

1 个答案:

答案 0 :(得分:1)

context.UserData

将使用您已实施的自定义状态客户端。

var stateClient = new StateClient(botCred);

将使用默认状态客户端。如果你想使用你在对话框之外实现的状态客户端,那么直接创建它的实例(你实现的那个)并使用它。

编辑:

目前没有强制StateClient使用自定义IBotDataStore的方法。但是,您可以创建IBotDataStore实现并直接使用它。以下是在对话框外使用自定义IBotDataStore实现的示例:(这基于https://blog.botframework.com/2017/07/26/Saving-State-Sql-Dotnet/

var store = new SqlBotDataStore("BotDataContextConnectionString") as IBotDataStore<BotData>;

var address = new Address()
    {
        BotId = activity.Recipient.Id,
        ChannelId = activity.ChannelId,
        ConversationId = activity.Conversation.Id,
        ServiceUrl = activity.ServiceUrl,
        UserId = activity.From.Id
    };

var botData = await store.LoadAsync(address, BotStoreType.BotUserData, new System.Threading.CancellationToken());
var dataInfo = botData.GetProperty<BotDataInfo>(BotStoreType.BotUserData.ToString()) ?? new BotDataInfo();               
dataInfo.Count++; 
botData.SetProperty(BotStoreType.BotUserData.ToString(), dataInfo);
await store.SaveAsync(address, BotStoreType.BotUserData, botData, new System.Threading.CancellationToken());