问题
I'm trying to access the complete original text from within a method marked as a LuisIntent
within a LuisDialog
.
The documentation shows these methods as taking two arguments:
IDialogContext context, LuisResult result
Neither of which publicly exposes the original text of the message. The context object does contain the message but in a private property (context.data.message.text
) which is not accessible.
Is there a way to access this in the context
, or can it be passed into the dialog constructor?
回答1:
You can override the MessageReceived(...) function of the LuisDialog keep the fields of the message that you need as member variables and access those fields in your intent handlers. Below I modified the SimpleAlarmDialog to show how you can access 'message.Text' in one of the intent handlers:
[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);
}
}
回答2:
With the new version of Bot Framework (1.0.2) the LuisResult object now has a Query parameter that contains the original query sent to LUIS.
回答3:
If you break into the method, you can see in the quick watch that the context object has a non-public property through to context.data.mesage.Text (note the misspelling of "mesage"). Since the property is non-public, you could cheat by using reflection to get at it (see GetInstanceField in How to get the value of private field in C#?)
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;
回答4:
You could do it like this by using the Query property of the LuisResult,
[LuisIntent(intentName: "someIntentName")]
private async Task Eligibility(IDialogContext context, LuisResult result)
{
await context.PostAsync($"The original text is: {result.Query}");
context.Wait(MessageReceivedAsync);
}
来源:https://stackoverflow.com/questions/36482531/how-do-you-get-to-the-original-message-text-in-a-microsoft-bot-framework-luisint