如何在 Microsoft Bot Framework LuisIntent 方法中获取原始消息文本
How do you get to the original message text in a Microsoft Bot Framework LuisIntent method
我正在尝试从 LuisDialog
中标记为 LuisIntent
的方法中访问完整的原始文本。
文档显示这些方法采用两个参数:
IDialogContext context, LuisResult result
两者均未公开消息的原文。上下文对象确实包含消息,但在私有 属性 (context.data.message.text
) 中,这是不可访问的。
有没有办法在 context
中访问它,或者可以将它传递到对话框构造函数中?
如果你进入这个方法,你可以在快速观察中看到上下文对象有一个非 public 属性 到 context.data.mesage.Text (注意 context.data.mesage.Text 的拼写错误=14=]).由于 属性 不是 public,您可以通过使用反射来作弊(请参阅 How to get the value of private field in C#? 中的 GetInstanceField)
Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData data = GetInstanceField(typeof (Microsoft.Bot.Builder.Dialogs.Internals.DialogContext), context, "data") as Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData;
Microsoft.Bot.Connector.Message originalMessage = GetInstanceField(typeof(Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData), data, "mesage") as Microsoft.Bot.Connector.Message;
string originalMessageText = originalMessage.Text;
您可以覆盖 LuisDialog 的 MessageReceived(...) 函数,将您需要的消息字段保留为成员变量,并在您的意图处理程序中访问这些字段。下面我修改了 SimpleAlarmDialog 以显示如何在一个意图处理程序中访问 'message.Text':
[LuisModel("c413b2ef-382c-45bd-8ff0-f76d60e2a821", "6d0966209c6e4f6b835ce34492f3e6d9")]
[Serializable]
public class SimpleAlarmDialog : LuisDialog<object>
{
private readonly Dictionary<string, Alarm> alarmByWhat = new Dictionary<string, Alarm>();
[Serializable]
public class PartialMessage
{
public string Text { set; get; }
}
private PartialMessage message;
protected override async Task MessageReceived(IDialogContext context, IAwaitable<Message> item)
{
var msg = await item;
this.message = new PartialMessage { Text = msg.Text };
await base.MessageReceived(context, item);
}
[LuisIntent("builtin.intent.alarm.delete_alarm")]
public async Task DeleteAlarm(IDialogContext context, LuisResult result)
{
await context.PostAsync($"echo: {message.Text}");
Alarm alarm;
if (TryFindAlarm(result, out alarm))
{
this.alarmByWhat.Remove(alarm.What);
await context.PostAsync($"alarm {alarm} deleted");
}
else
{
await context.PostAsync("did not find alarm");
}
context.Wait(MessageReceived);
}
}
在新版本的 Bot Framework (1.0.2) 中,LuisResult 对象现在有一个包含原始查询的 Query 参数发送到 LUIS。
您可以通过使用 LuisResult
的查询 属性 来做到这一点
[LuisIntent(intentName: "someIntentName")]
private async Task Eligibility(IDialogContext context, LuisResult result)
{
await context.PostAsync($"The original text is: {result.Query}");
context.Wait(MessageReceivedAsync);
}
我正在尝试从 LuisDialog
中标记为 LuisIntent
的方法中访问完整的原始文本。
文档显示这些方法采用两个参数:
IDialogContext context, LuisResult result
两者均未公开消息的原文。上下文对象确实包含消息,但在私有 属性 (context.data.message.text
) 中,这是不可访问的。
有没有办法在 context
中访问它,或者可以将它传递到对话框构造函数中?
如果你进入这个方法,你可以在快速观察中看到上下文对象有一个非 public 属性 到 context.data.mesage.Text (注意 context.data.mesage.Text 的拼写错误=14=]).由于 属性 不是 public,您可以通过使用反射来作弊(请参阅 How to get the value of private field in C#? 中的 GetInstanceField)
Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData data = GetInstanceField(typeof (Microsoft.Bot.Builder.Dialogs.Internals.DialogContext), context, "data") as Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData;
Microsoft.Bot.Connector.Message originalMessage = GetInstanceField(typeof(Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData), data, "mesage") as Microsoft.Bot.Connector.Message;
string originalMessageText = originalMessage.Text;
您可以覆盖 LuisDialog 的 MessageReceived(...) 函数,将您需要的消息字段保留为成员变量,并在您的意图处理程序中访问这些字段。下面我修改了 SimpleAlarmDialog 以显示如何在一个意图处理程序中访问 'message.Text':
[LuisModel("c413b2ef-382c-45bd-8ff0-f76d60e2a821", "6d0966209c6e4f6b835ce34492f3e6d9")]
[Serializable]
public class SimpleAlarmDialog : LuisDialog<object>
{
private readonly Dictionary<string, Alarm> alarmByWhat = new Dictionary<string, Alarm>();
[Serializable]
public class PartialMessage
{
public string Text { set; get; }
}
private PartialMessage message;
protected override async Task MessageReceived(IDialogContext context, IAwaitable<Message> item)
{
var msg = await item;
this.message = new PartialMessage { Text = msg.Text };
await base.MessageReceived(context, item);
}
[LuisIntent("builtin.intent.alarm.delete_alarm")]
public async Task DeleteAlarm(IDialogContext context, LuisResult result)
{
await context.PostAsync($"echo: {message.Text}");
Alarm alarm;
if (TryFindAlarm(result, out alarm))
{
this.alarmByWhat.Remove(alarm.What);
await context.PostAsync($"alarm {alarm} deleted");
}
else
{
await context.PostAsync("did not find alarm");
}
context.Wait(MessageReceived);
}
}
在新版本的 Bot Framework (1.0.2) 中,LuisResult 对象现在有一个包含原始查询的 Query 参数发送到 LUIS。
您可以通过使用 LuisResult
的查询 属性 来做到这一点[LuisIntent(intentName: "someIntentName")]
private async Task Eligibility(IDialogContext context, LuisResult result)
{
await context.PostAsync($"The original text is: {result.Query}");
context.Wait(MessageReceivedAsync);
}