C# 使用带有反馈的QnAMaker示例时出错
我一直在尝试将Microsoft认知和AI工具包与C# 使用带有反馈的QnAMaker示例时出错,c#,botframework,qnamaker,C#,Botframework,Qnamaker,我一直在尝试将Microsoft认知和AI工具包与QnAMakerAPI结合使用,以创建一个简单的聊天机器人 虽然我的普通qnaMakerAi聊天机器人工作正常,但在我尝试增强其功能并在响应中包含机器人反馈时出现了一个问题 我一直遵循所提到的确切代码示例 我遇到的问题是: Exception: Object reference not set to an instance of an object. [File of type 'text/plain']. 调试器在代码段中(在文件WebAp
QnAMaker
API结合使用,以创建一个简单的聊天机器人
虽然我的普通qnaMakerAi聊天机器人工作正常,但在我尝试增强其功能并在响应中包含机器人反馈时出现了一个问题
我一直遵循所提到的确切代码示例
我遇到的问题是:
Exception: Object reference not set to an instance of an object.
[File of type 'text/plain'].
调试器在代码段中(在文件WebApiConfig.cs中)出现错误
我也在-,对这个问题作了详细的描述
请检查并提出建议
根据用户评论,以下是MessagesController的代码-
using System;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.Dialogs;
using System.Web.Http.Description;
using System.Net.Http;
using QnABot.Dialogs;
namespace Microsoft.Bot.Sample.QnABot
{
[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// receive a message from a user and send replies
/// </summary>
/// <param name="activity"></param>
[ResponseType(typeof(void))]
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
// check if activity is of type message
if (activity.GetActivityType() == ActivityTypes.Message)
{
//await Conversation.SendAsync(activity, () => new RootDialog());
await Conversation.SendAsync(activity, () => new QnaDialog());
}
else
{
HandleSystemMessage(activity);
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
}
使用系统;
使用System.Threading.Tasks;
使用System.Web.Http;
使用Microsoft.Bot.Connector;
使用Microsoft.Bot.Builder.Dialogs;
使用System.Web.Http.Description;
使用System.Net.Http;
使用QnABot.Dialogs;
命名空间Microsoft.Bot.Sample.QnABot
{
[身份验证]
公共类消息控制器:ApiController
{
///
///帖子:api/Messages
///接收来自用户的消息并发送回复
///
///
[响应类型(typeof(void))]
公共虚拟异步任务发布([FromBody]活动)
{
//检查活动是否为消息类型
if(activity.GetActivityType()==ActivityTypes.Message)
{
//wait Conversation.sendaync(活动,()=>newrootdialog());
wait Conversation.SendAsync(活动,()=>new QnaDialog());
}
其他的
{
HandleSystemMessage(活动);
}
返回新的HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
私有活动HandleSystemMessage(活动消息)
{
if(message.Type==ActivityTypes.DeleteUserData)
{
//在此处执行用户删除
//如果我们处理用户删除,返回一条真实的消息
}
else if(message.Type==ActivityTypes.ConversationUpdate)
{
//处理会话状态更改,如添加和删除成员
//使用Activity.MembersAdded和Activity.MembersRemoved以及Activity.Action获取信息
//并非所有频道都可用
}
else if(message.Type==ActivityTypes.ContactRelationUpdate)
{
//处理联系人列表中的添加/删除
//Activity.From+Activity.Action表示发生了什么
}
else if(message.Type==ActivityTypes.Typing)
{
//处理知道用户正在键入的内容
}
else if(message.Type==ActivityTypes.Ping)
{
}
返回null;
}
}
}
对于QnADialog-
using Microsoft.Bot.Builder.Azure;
using Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace QnABot.Dialogs
{
[Serializable]
public class QnaDialog : QnAMakerDialog
{
public QnaDialog() : base(new QnAMakerService(new QnAMakerAttribute("b372e477-0a2f-4a5a-88d5-3a664d16a4c3", "4ee02ead3xxxxxx", "Sorry, I couldn't find an answer for that", 0.5)))
{
}
protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
{
// answer is a string
var answer = result.Answers.First().Answer;
Activity reply = ((Activity)context.Activity).CreateReply();
string[] qnaAnswerData = answer.Split(';');
int dataSize = qnaAnswerData.Length;
string title = qnaAnswerData[0];
string description = qnaAnswerData[1];
string url = qnaAnswerData[2];
string imageURL = qnaAnswerData[3];
HeroCard card = new HeroCard
{
Title = title,
Subtitle = description,
};
card.Buttons = new List<CardAction>
{
new CardAction(ActionTypes.OpenUrl, "Learn More", value: url)
};
card.Images = new List<CardImage>
{
new CardImage( url = imageURL)
};
reply.Attachments.Add(card.ToAttachment());
await context.PostAsync(reply);
}
protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
{
// get the URL
var answer = result.Answers.First().Answer;
string[] qnaAnswerData = answer.Split(';');
string qnaURL = qnaAnswerData[2];
// pass user's question
var userQuestion = (context.Activity as Activity).Text;
context.Call(new FeedbackDialog(qnaURL, userQuestion), ResumeAfterFeedback);
}
private async Task ResumeAfterFeedback(IDialogContext context, IAwaitable<IMessageActivity> result)
{
if (await result != null)
{
await MessageReceivedAsync(context, result);
}
else
{
context.Done<IMessageActivity>(null);
}
}
}
}
使用Microsoft.Bot.Builder.Azure;
使用Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
使用Microsoft.Bot.Builder.Dialogs;
使用Microsoft.Bot.Connector;
使用制度;
使用System.Collections.Generic;
使用系统配置;
使用System.Linq;
使用System.Threading.Tasks;
使用System.Web;
名称空间QnABot.Dialogs
{
[可序列化]
公共类QnaDialog:QnAMakerDialog
{
public QnaDialog():base(新的QnAMakerService(新的QnAMakerAttribute(“b372e477-0a2f-4a5a-88d5-3a664d16a4c3”,“4EE02EAD3xxxxx”,“对不起,我找不到答案”,0.5)))
{
}
受保护的重写异步任务RespondFromQnAMakerResultAsync(IDialogContext上下文、IMessageActivity消息、QnAMakerResults结果)
{
//答案是一个字符串
var answer=result.Answers.First().answer;
活动回复=((活动)context.Activity).CreateReply();
字符串[]qnaAnswerData=answer.Split(“;”);
int dataSize=qnaAnswerData.Length;
字符串title=qnaAnswerData[0];
字符串描述=qnaAnswerData[1];
字符串url=qnaAnswerData[2];
字符串imageURL=qnaAnswerData[3];
HeroCard=新的HeroCard
{
头衔,
副标题=描述,
};
card.Buttons=新列表
{
新的CardAction(ActionTypes.OpenUrl,“了解更多”,值:url)
};
card.Images=新列表
{
新建CardImage(url=imageURL)
};
reply.Attachments.Add(card.ToAttachment());
等待上下文。PostAsync(回复);
}
受保护的重写异步任务DefaultWaitNextMessageAsync(IDialogContext上下文、IMessageActivity消息、QnAMakerResults结果)
{
//获取URL
var answer=result.Answers.First().answer;
字符串[]qnaAnswerData=answer.Split(“;”);
字符串qnaURL=qnaAnswerData[2];
//传递用户的问题
var userQuestion=(context.Activity作为Activity).Text;
调用(新反馈对话框(qnaURL,userQuestion),ResumeAfterFeedback);
}
私有异步任务ResumeAfterFeedback(IDialogContext上下文,IAwaitable结果)
{
if(等待结果!=null)
{
等待消息ReceivedAsync(上下文、结果);
}
其他的
{
context.Done(null);
}
}
}
}
对于反馈对话框-
using Microsoft.ApplicationInsights;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace QnABot.Dialogs
{
[Serializable]
public class FeedbackDialog : IDialog<IMessageActivity>
{
private string qnaURL;
private string userQuestion;
public FeedbackDialog(string url, string question)
{
// keep track of data associated with feedback
qnaURL = url;
userQuestion = question;
}
public async Task StartAsync(IDialogContext context)
{
var feedback = ((Activity)context.Activity).CreateReply("Did you find what you need?");
feedback.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction(){ Title = "1st, bad config
Ok, the 1st problem is the fact that you inverted 2 parameters in your QnaDialog declaration:
public QnaDialog() : base(new QnAMakerService(new QnAMakerAttribute("b372e477-0a2f-4a5a-88d5-3a664d16a4c3", "4ee02ead3xxxxxx", "Sorry, I couldn't find an answer for that", 0.5)))
使用Microsoft.ApplicationInsights;
使用Microsoft.Bot.Builder.Dialogs;
使用Microsoft.Bot.Connector;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用System.Web;
名称空间QnABot.Dialogs
{
[可序列化]
公共类反馈对话框:IDialog
{
私有字符串qnaURL;
私有字符串用户问题;
公众反馈
using Microsoft.ApplicationInsights;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace QnABot.Dialogs
{
[Serializable]
public class FeedbackDialog : IDialog<IMessageActivity>
{
private string qnaURL;
private string userQuestion;
public FeedbackDialog(string url, string question)
{
// keep track of data associated with feedback
qnaURL = url;
userQuestion = question;
}
public async Task StartAsync(IDialogContext context)
{
var feedback = ((Activity)context.Activity).CreateReply("Did you find what you need?");
feedback.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction(){ Title = "1st, bad config
Ok, the 1st problem is the fact that you inverted 2 parameters in your QnaDialog declaration:
public QnaDialog() : base(new QnAMakerService(new QnAMakerAttribute("b372e477-0a2f-4a5a-88d5-3a664d16a4c3", "4ee02ead3xxxxxx", "Sorry, I couldn't find an answer for that", 0.5)))
public QnAMakerAttribute(string subscriptionKey, string knowledgebaseId, ...
protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
{
// answer is a string
var answer = result.Answers.First().Answer;
Activity reply = ((Activity)context.Activity).CreateReply();
var qnaAnswerData = answer.Split(';');
var dataSize = qnaAnswerData.Length;
if (dataSize == 3)
{
var title = qnaAnswerData[0];
var description = qnaAnswerData[1];
var url = qnaAnswerData[2];
var imageUrl = qnaAnswerData[3];
var card = new HeroCard
{
Title = title,
Subtitle = description,
Buttons = new List<CardAction>
{
new CardAction(ActionTypes.OpenUrl, "Learn More", value: url)
},
Images = new List<CardImage>
{
new CardImage(url = imageUrl)
},
};
reply.Attachments.Add(card.ToAttachment());
}
else
{
reply.Text = answer;
}
await context.PostAsync(reply);
}
protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
{
if (result.Answers.Count > 0)
{
// get the URL
var answer = result.Answers.First().Answer;
var qnaAnswerData = answer.Split(';');
var dataSize = qnaAnswerData.Length;
if (dataSize == 3)
{
var qnaUrl = qnaAnswerData[2];
// pass user's question
var userQuestion = (context.Activity as Activity).Text;
context.Call(new FeedbackDialog(qnaUrl, userQuestion), ResumeAfterFeedback);
}
else
{
await ResumeAfterFeedback(context, new AwaitableFromItem<IMessageActivity>(null));
}
}
else
{
await ResumeAfterFeedback(context, new AwaitableFromItem<IMessageActivity>(null));
}
}
private async Task ResumeAfterFeedback(IDialogContext context, IAwaitable<IMessageActivity> result)
{
if (await result != null)
{
await MessageReceivedAsync(context, result);
}
else
{
context.Done<IMessageActivity>(null);
}
}