Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Microsoft bot框架:如何集成登录对话框并等待登录结果_C#_Authentication_Async Await_Botframework - Fatal编程技术网

C#Microsoft bot框架:如何集成登录对话框并等待登录结果

C#Microsoft bot框架:如何集成登录对话框并等待登录结果,c#,authentication,async-await,botframework,C#,Authentication,Async Await,Botframework,我正在尝试在我的团队机器人中包括登录选项。我从git hub获取了示例代码,并将其包含在代码中 我只希望用户在特殊情况下登录,例如当他想要预订房间时 问题是在登录完成之前,bot将进入下一步并失败 case LUISIntent.FindRoom: token = await _authToken.GetAsync(turnContext, () => token);

我正在尝试在我的团队机器人中包括登录选项。我从git hub获取了示例代码,并将其包含在代码中

我只希望用户在特殊情况下登录,例如当他想要预订房间时

问题是在登录完成之前,bot将进入下一步并失败

                        case LUISIntent.FindRoom:

                            token = await _authToken.GetAsync(turnContext, () => token);
                            if (token.IsNullOrWhiteSpace())
                            {
                                var resultToken = dc.BeginDialogAsync(nameof(SignInDialog),
                                    cancellationToken: cancellationToken);
                                if (resultToken.Status != TaskStatus.WaitingForActivation)
                                {
                                    var tokenResponse = resultToken.Result;
                                    var tokenResult = (TokenResponse)tokenResponse.Result;
                                    token = tokenResult.Token;
                                    await _authToken.SetAsync(turnContext, token, cancellationToken);
                                }

                            }

                            await dc.BeginDialogAsync(nameof(FindRoom), luisResults);

问题是如何以更好的方式集成登录,以及如何在收到登录对话框的返回响应之前停止执行

如果您希望bot基本上“暂停”直到返回令牌,我将完全按照示例bot所示执行。它有一个瀑布式对话框,循环直到显示成功的令牌响应

AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
           {
               PromptStepAsync,
               LoginStepAsync,
               DisplayTokenPhase1Async,
               DisplayTokenPhase2Async,
           }));

           // The initial child Dialog to run.
           InitialDialogId = nameof(WaterfallDialog);
       }

       private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
       {
           return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
       }

private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
       {
           // Get the token from the previous step. Note that we could also have gotten the
           // token directly from the prompt itself. There is an example of this in the next method.
           var tokenResponse = (TokenResponse)stepContext.Result;
           if (tokenResponse != null)
           {
               await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged in."), cancellationToken);
               return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to view your token?") }, cancellationToken);
           }

           await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);
           return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
       }
AddDialog(新建WaterWallDialog(名称)(WaterWallDialog),新建WaterWallStep[]
{
PromptStepAsync,
LoginStepAsync,
DisplayTokenPhase1Async,
DisplayTokenPhase2Async,
}));
//要运行的初始子对话框。
InitialDialogId=nameof(WaterWallDialog);
}
专用异步任务PromptStepAsync(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
返回wait-stepContext.BeginDialogAsync(nameof(OAuthPrompt),null,cancellationToken);
}
专用异步任务LoginStepAsync(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
//从上一步获取令牌。请注意,我们还可以获取
//直接从提示符本身获取令牌。下一个方法中有一个例子。
var tokenResponse=(tokenResponse)stepContext.Result;
if(令牌响应!=null)
{
等待stepContext.Context.SendActivityAsync(MessageFactory.Text(“您现在已登录”)、cancellationToken;
return wait-stepContext.PromptAsync(nameof(confirmport),newpromptoptions{Prompt=MessageFactory.Text(“您想查看您的令牌吗?”)},cancellationToken);
}
Wait stepContext.Context.SendActivityAsync(MessageFactory.Text(“登录未成功,请重试”)、cancellationToken);
return wait stepContext.EndDialogAsync(cancellationToken:cancellationToken);
}
从这两个步骤中可以看到,它会提示,然后进行检查。如果检查失败,它将结束对话框,这意味着当bot再次收到消息时,瀑布将重新开始。这将继续进行,直到返回令牌,然后转到“是否希望看到您的令牌”提示。很明显,你不会问你的客户是否想看他们的代币,但这个想法是可靠的

case LUISIntent.FindRoom:

//TINY WATERFALL HERE
//this waterfall would be added to your dialogs wherever you add them. 
//for the sake of brevity, i'm skipping that part


//WATERFALL STEP 1:
private async Task<DialogTurnResults> GETTINGYOURLOGIN(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    token = await _authToken.GetAsync(turnContext, () => token);
    return await stepContext.NextAsync(cancellationToken);
}
//WATERFALL STEP 2:

private async Task<DialogTurnResults> CHECKINGYOURLOGIN(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{

// Get the token from the previous step.
//this does a quick check to see if it's NOT null, then goes to the next step.
//OTHERWISE, it continues with your login prompt.
//this way, if your user has ALREADY logged in, and for whatever reason goes BACK to the //book room dialog, they don't have to re-login if it's been a short enough time

if (!token.IsNullOrWhiteSpace())
{
   await dc.BeginDialogAsync(nameof(FindRoom), luisResults);
}

var resultToken = dc.BeginDialogAsync(nameof(SignInDialog),
            cancellationToken: cancellationToken);

if (resultToken.Status != TaskStatus.WaitingForActivation)
{
    var tokenResponse = resultToken.Result;
    var tokenResult = (TokenResponse)tokenResponse.Result;
    token = tokenResult.Token;
    await _authToken.SetAsync(turnContext, token, cancellationToken);
}
// Replace on the stack the current instance of the waterfall with a new instance,
// and start from the top.
return await stepContext.ReplaceDialogAsync(nameof(YOURMINIWATERFALLDIALOG), cancellationToken: cancellationToken);

}
case luisint.FindRoom:
//这里的小瀑布
//无论您在何处添加对话框,都会将此瀑布添加到对话框中。
//为了简洁起见,我跳过了那部分
//瀑布式步骤1:
私有异步任务GETTINGYOURLOGIN(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
token=await_authToken.GetAsync(turnContext,()=>token);
返回Wait-stepContext.NextAsync(cancellationToken);
}
//瀑布式步骤2:
私有异步任务检查您的登录(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
//从上一步获取令牌。
//这会快速检查它是否为null,然后进入下一步。
//否则,它将在登录提示下继续。
//这样,如果您的用户已经登录,并且出于任何原因返回到//book room对话框,那么如果时间足够短,他们就不必重新登录
如果(!token.IsNullOrWhiteSpace())
{
Wait dc.BeginDialogAsync(姓名(FindRoom),luisResults);
}
var resultToken=dc.BeginDialogAsync(名称(SignInDialog),
cancellationToken:cancellationToken);
if(resultToken.Status!=任务状态。等待激活)
{
var tokenResponse=resultToken.Result;
var tokenResult=(TokenResponse)TokenResponse.Result;
token=tokenResult.token;
wait_authToken.SetAsync(turnContext、token、cancellationToken);
}
//在堆栈上用新实例替换瀑布的当前实例,
//从顶部开始。
return wait stepContext.ReplaceDialogAsync(名称为(您的MiniWaterCallDialog),cancellationToken:cancellationToken);
}
这真的很粗糙,但它应该足以让你大致了解我的意思。通过将您所说的失败的延续删除到它自己的依赖于令牌的if检查中,您将无法在没有有效的延续的情况下继续,从而失败