有没有办法让"新的状态客户端(botCred)"将用户数据保存到使用自定义IBotDataStore的机器人



我正在尝试在我的机器人上实现自定义身份验证,如本文的模式 A 中所述。 但是,我的 Web 应用程序尝试写入我的 BotStateDataStore 的数据未保留在其上,因此当我尝试从机器人本身读取它时不可用。

要点:

  • 我正在使用自定义IBot数据存储将状态保存在我自己的SQL服务器数据库中。当我尝试从机器人本身(已经过测试(中的代码中保存数据时,它正在工作。

我刚刚在我的机器人的同一解决方案上创建了一个新的 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;
}
}
}

问题是,当我尝试在机器人中获取"profile"值时,对上述代码的鄙视正在执行,没有任何异常,如下面的代码所示,

context.UserData.TryGetValue<string>(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;
}
}

任何人都可以告诉我如何在我的机器人的botStateStore中从 asp.net Web MVC应用程序中编写一些值,witch是另一个botframework(Asp.Net.WebApi(应用程序?

context.UserData

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

var stateClient = new StateClient(botCred);

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


编辑:

目前没有强制状态客户端使用自定义 IBotData Store 的方法。 但是,您可以只创建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());

最新更新