我使用Bot Framework和AzureAuthDialog来验证用户身份。
机器人首先询问用户他想要什么。每当用户写入消息时,我们都会检查他是否经过身份验证。如果我们发现他未经过身份验证,我们会要求他进行身份验证。一旦完成身份验证,我希望在身份验证之前继续处理他的请求。
另一方面,目前发生的情况是,在用户进行身份验证后,我们会丢失用户消息。这是代码,请参阅内联注释以了解更多信息:
public class IntentHandler : LuisDialog<object>
{
protected override async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> item)
{
if (!await context.IsUserAuthenticated(m_resourceId))
{
// this has the user's message
var message = await item;
// The next thing that is called here is ResumeAfterAuth function, but it does not have the user's message anymore
await context.Forward(new AzureAuthDialog(m_resourceId), ResumeAfterAuth, message, CancellationToken.None);
}
else
{
await base.MessageReceived(context, item);
}
}
private async Task ResumeAfterAuth(IDialogContext context, IAwaitable<string> item)
{
// this does not have the users's message, it only includes "User is loged in"
var message = await item;
await context.PostAsync(message);
PrivateTracer.Tracer.TraceInformation($"User {context.GetUserMail()} signed in");
await context.PostAsync(c_welcomeQuestion);
}
}
知道如何在身份验证之前传递用户消息吗?
我知道我可以在MessageReceived enter code here
的字段中保存用户的消息,但这看起来太难看了。还有另一种方式吗?
答案 0 :(得分:1)
ResumeAfterAuth 方法中的 IAwaitable 是您调用的对话框( AzureAuthDialog )的结果,而不是初始用户的消息。< / p>
如果您不拥有 AzureAuthDialog ,则需要保留原始消息并将其传递给回调( ResumeAfterAuth )。您可以将它保存为对话框类的成员变量或通过lambda函数的clousure保存,如下所示:
if (!await context.IsUserAuthenticated(m_resourceId))
{
var initialUserText = (await item).Text;
await context.Forward(new AzureAuthDialog(m_resourceId), (_context, _item) => ResumeAfterAuth(_context, _item, initialUserText), message, CancellationToken.None);
}
您的回调方法签名如下所示:
private async Task ResumeAfterAuth(IDialogContext context, IAwaitable<string> item, string initialUserText)
如果您拥有 AzureAuthDialog ,我猜您最好在完成后将原始用户文本返回给您。
编辑:您需要配置BotFramework以允许它序列化闭包,如果您还没有,则described here。您可以通过将其添加到服务的启动方法来实现:
var builder = new ContainerBuilder();
builder.RegisterModule(new ReflectionSurrogateModule());
builder.Update(Conversation.Container);
答案 1 :(得分:0)
@andre提到的是一种方法,另一种方法是将用户消息存储在本地变量中,然后在认证后将存储的用户消息传递给它时调用base.MessageReceived函数。代码通常是这样的:
IndustryName Country A Country B Country C
Industry A 2 1 NULL
Industry B 3 NULL NULL