Botframework 有没有办法做一个';new StateClient(botCred)将用户数据保存到使用自定义IBotDataStore的bot

Botframework 有没有办法做一个';new StateClient(botCred)将用户数据保存到使用自定义IBotDataStore的bot,botframework,Botframework,我正在尝试在我的bot上实现,如模式a中所述。 但是,我的Web应用程序试图写入我的BotStateDataStore的数据没有在其上持久化,因此,当我尝试从bot本身读取数据时,数据不可用 要点: 我正在使用一个自定义IBotDataStore。当我试图将代码中的数据保存到bot本身(已经测试过)时,它就起作用了 我刚刚在我的bot的同一解决方案上创建了一个新的asp.net web应用程序,设置了de bot web.Config上使用的相同MicrosoftAppId和Microsof

我正在尝试在我的bot上实现,如模式a中所述。 但是,我的Web应用程序试图写入我的BotStateDataStore的数据没有在其上持久化,因此,当我尝试从bot本身读取数据时,数据不可用

要点:

  • 我正在使用一个自定义IBotDataStore。当我试图将代码中的数据保存到bot本身(已经测试过)时,它就起作用了
我刚刚在我的bot的同一解决方案上创建了一个新的asp.net web应用程序,设置了de bot web.Config上使用的相同MicrosoftAppId和MicrosoftAppPassword,并在新控制器上实现了以下方法,以便尝试持久化:

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;
        }
    }
}
公共类身份验证控制器:ApiController
{
//获取:api/身份验证
[HttpGet]
公共异步任务授权(字符串令牌)
{
尝试
{
var appId=ConfigurationManager.AppSettings[“MicrosoftAppId”];
var password=ConfigurationManager.AppSettings[“MicrosoftAppPassword”];
var botCred=新的MicrosoftAppCredentials(appId,密码);
var stateClient=新stateClient(botCred);
BotData BotData=新的BotData(eTag:“*”);
//假设我刚刚调用了一个内部服务来获取我的用户的配置文件,并获取了它的配置文件:
//让我们将其保存在botstate中,以使此信息可供bot使用,因为我需要它,以便根据用户的配置文件(匿名、可识别、高级或专业)选择与bot的不同对话框
botData.SetProperty('Profile','identificato');
var data=await stateClient.BotState.SetUserDataAsync(“directline”、“User1”、botData);
返回true;
}
捕获(例外情况除外)
{
返回false;
}
}
}
问题是,尽管上面的代码没有任何异常,但当我尝试在bot中获取“profile”值时,如下面的代码所示

context.UserData.TryGetValue<string>(stateKey, out perfil)
context.UserData.TryGetValue(stateKey,out perfil)
返回空值

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;
            }
        }
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
var消息=等待结果;
尝试
{
context.UserData.SetValue(“Perfil”、“XXXXXXXXX”);
字符串perfil;
if(context.UserData.TryGetValue(stateKey,out perfil))
{
wait context.PostAsync($“Olá,fulano seu perfilé{perfil}'”);
}
其他的
{
wait context.PostAsync($“ola,anônimo”);
}
}
捕获(例外情况除外)
{
掷骰子;
}
if(message.Text==null | | message.Text.Equals(GlobalResources.Back,StringComparison.InvariantCultureIgnoreCase))
{//Quando entra nese diálogo a 1ªvez ou volta de um dialogo filho。
var rootCard=GetCard();
var reply=context.MakeMessage();
回复.附件.添加(rootCard);
等待上下文。PostAsync(回复);
Wait(MessageReceivedAsync);
}
else if(message.Text.Equals(GlobalResources.AboutToro、StringComparison.invariantCultureInogoreCase))
{
调用(新的AboutToroDialog(),OnResumeToRootDialog);
}
其他的
{
var messageToForward=等待结果;
wait context.Forward(new QnADialog(),AfterFAQDialog,messageToForward,CancellationToken.None);
返回;
}
}
有谁能告诉我,我如何在我的bot的botStateStore中编写asp.net web MVC应用程序的值,这是另一个botframework(asp.net.WebApi)应用程序

context.UserData
将使用已实现的自定义状态客户端

var stateClient = new StateClient(botCred);
将使用默认的状态客户端。如果要在对话框外部使用已实现的状态客户端,请直接创建它的实例(已实现的实例)并使用该实例


编辑:

目前没有强制StateClient使用自定义IBMotDataStore的方法。但是,您可以创建IBotDataStore实现并直接使用它。下面是一个在对话框之外使用自定义IBotDataStore实现的示例:(这基于)

var store=新的SqlBotDataStore(“BotDataContextConnectionString”)作为IBotDataStore;
var address=新地址()
{
BotId=activity.Recipient.Id,
ChannelId=活动。ChannelId,
ConversationId=activity.Conversation.Id,
ServiceUrl=activity.ServiceUrl,
UserId=activity.From.Id
};
var botData=await store.LoadAsync(地址,BotStoreType.BotUserData,new System.Threading.CancellationToken());
var dataInfo=botData.GetProperty(BotStoreType.BotUserData.ToString())??新的BotDataInfo();
dataInfo.Count++;
SetProperty(BotStoreType.BotUserData.ToString(),dataInfo);
wait store.SaveAsync(地址,BotStoreType.BotUserData,botData,new System.Threading.CancellationToken());

是的,你是对的,我刚刚测试了上面的代码,没有使用我的定制SqlServerBotDataStore,它工作了,因为Bot和Web应用程序(外部witch使用“new StateClient(botCred)”)都使用MSFT提供的默认IBotDataStore;有没有办法将我的SqlServerBotDataStore设置为与“new StateClient(botCred);”一起使用目前还没有让StateClient使用自定义IBMotDataStore的方法
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());