【发布时间】:2019-10-02 11:25:15
【问题描述】:
我使用 C# 使用 bot 框架 v4 制作了一个机器人,它位于网页 https://websitebotv2.azurewebsites.net/ 上,如果只有 1 个用户,它可以正常工作,但是当我在新选项卡上打开它时,它会在我开始时给出 IndexOutOfRangeException对话。
我需要做什么才能使其在打开多个选项卡的情况下工作?
当我的机器人加注星标时,它会创建一个瀑布对话框,询问用户姓名并问候用户:
public dialogBotBot(dialogBotAccessors accessors, LuisRecognizer luis, QnAMaker qna)
{
// Set the _accessors
_accessors = accessors ?? throw new ArgumentNullException(nameof(accessors));
// The DialogSet needs a DialogState accessor, it will call it when it has a turn context.
_dialogs = new DialogSet(accessors.ConversationDialogState);
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[] {
NameStepAsync,
NameConfirmStepAsync,
};
// The incoming luis variable is the LUIS Recognizer we added above.
this.Recognizer = luis ?? throw new System.ArgumentNullException(nameof(luis));
// The incoming QnA variable is the QnAMaker we added above.
this.QnA = qna ?? throw new System.ArgumentNullException(nameof(qna));
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
_dialogs.Add(new WaterfallDialog("details", waterfallSteps));
_dialogs.Add(new TextPrompt("name"));
}
然后我将他的名字保存在 UserProfile 类中,其中包含字段 Name 和 Context,Context 的目的是保存对话。
这是第一次工作,但如果我打开一个新标签或刷新当前标签以进行新对话,机器人将获取第一个对话数据。
在 Startup.cs 中抛出异常:
services.AddBot<dialogBotBot>(options =>
{
options.CredentialProvider = new ConfigurationCredentialProvider(Configuration);
// Catches any errors that occur during a conversation turn and logs them to currently
// configured ILogger.
ILogger logger = _loggerFactory.CreateLogger<dialogBotBot>();
options.OnTurnError = async (context, exception) =>
{
logger.LogError($"Exception caught : {exception}");
await context.SendActivityAsync(exception + "\nSorry, it looks like something went wrong.\n" + exception.Message);
};
// Create and add conversation state.
var conversationState = new ConversationState(dataStore);
options.State.Add(conversationState);
// Create and add user state.
var userState = new UserState(dataStore);
options.State.Add(userState);
});
我的 onTurnAsync 方法是:
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
// Handle Message activity type, which is the main activity type for shown within a conversational interface
// Message activities may contain text, speech, interactive cards, and binary or unknown attachments.
// see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types
if (turnContext.Activity.Type == ActivityTypes.Message)
{
//Get the current user profile
userProfile = await _accessors.UserProfile.GetAsync(turnContext, () => new UserProfile(), cancellationToken);
userProfile.Contexto.Add(turnContext.Activity.Text);
foreach (string s in userProfile.Contexto)
await turnContext.SendActivityAsync(s);
// Get the conversation state from the turn context.
var state = await _accessors.CounterState.GetAsync(turnContext, () => new CounterState());
// Bump the turn count for this conversation.
state.TurnCount++;
// Check LUIS model
var recognizerResult = await this.Recognizer.RecognizeAsync(turnContext, cancellationToken);
var topIntent = recognizerResult?.GetTopScoringIntent();
// Get the Intent as a string
string strIntent = (topIntent != null) ? topIntent.Value.intent : "";
// Get the IntentScore as a double
double dblIntentScore = (topIntent != null) ? topIntent.Value.score : 0.0;
// Only proceed with LUIS if there is an Intent
// and the score for the Intent is greater than 95
if (strIntent != "" && (dblIntentScore > 2))
{
switch (strIntent)
{
case "None":
//add the bot response to contexto
await turnContext.SendActivityAsync("Desculpa, não percebi.");
break;
case "Utilities_Help":
//add the bot response to contexto
await turnContext.SendActivityAsync("Quero-te ajudar!\nO que precisas?");
break;
default:
// Received an intent we didn't expect, so send its name and score.
//add the bot response to contexto
await turnContext.SendActivityAsync($"Intent: {topIntent.Value.intent} ({topIntent.Value.score}).");
break;
}
}
else
{
if (userProfile.Name == null)
{
// Run the DialogSet - let the framework identify the current state of the dialog from the dialog stack and figure out what (if any) is the active dialog.
var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
// If the DialogTurnStatus is Empty we should start a new dialog.
if (results.Status == DialogTurnStatus.Empty)
{
await dialogContext.BeginDialogAsync("details", null, cancellationToken);
}
}
else
{
var answers = await this.QnA.GetAnswersAsync(turnContext);
if (answers.Any() && answers[0].Score > 0.7)
{
// If the service produced one or more answers, send the first one.
await turnContext.SendActivityAsync(answers[0].Answer + "\n" + state.TurnCount);
}
else
{
var responseMessage = $"Ainda não sei a resposta mas vou averiguar\nPosso-te ajudar com mais alguma coisa?";
String connectionString = "Data Source=botdataserverv1.database.windows.net;" +
"Initial Catalog=botDataBase;" +
"User id=AzureAdmin@botdataserverv1.database.windows.net;" +
"Password=admin_123;";
SqlConnection connection = new SqlConnection(connectionString);
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand command;
String sms = turnContext.Activity.Text;
float result = answers[0].Score;
String insertMessage = "insert into Mensagem(texto,contexto,grauCerteza)" +
"values('" + sms + "', 'Falta apurar o contexto' ," + result + ")";
connection.Open();
command = new SqlCommand(insertMessage, connection);
adapter.InsertCommand = new SqlCommand(insertMessage, connection);
adapter.InsertCommand.ExecuteNonQuery();
command.Dispose();
connection.Close();
await turnContext.SendActivityAsync(responseMessage);
}
}
// Save the user profile updates into the user state.
await _accessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
// Set the property using the accessor.
await _accessors.CounterState.SetAsync(turnContext, state);
// Save the new turn count into the conversation state.
await _accessors.ConversationState.SaveChangesAsync(turnContext);
}
}
}
【问题讨论】:
-
抱歉,没有您的实施细节,我们无法帮助/理解/解释
-
我用更多信息编辑我的问题,希望对您有所帮助。我真的不知道为什么会这样
-
我在 5 个不同的选项卡中打开了您的机器人,它们似乎都可以正常工作。重现错误的步骤是什么?错误发生在哪一行代码?如果您可以链接到所有机器人代码,那将有所帮助。我在您包含的代码中没有看到任何会导致这种情况的内容。
-
如果我猜的话,这发生在
OnMembersAddedAsync,或类似的地方。 -
我现在无法在 Visual Studio 中安装 github 扩展,我稍后再试。在我的浏览器中,当我打开托管机器人的网页时,它可以正常工作,但是当我刷新网页而不是重新启动对话框时,它会给我这个异常,尽管如果我继续从我的 QnA 提出问题,他会回复我. Startup.cs中抛出异常,我将代码放在问题中。
标签: botframework