2016-04-07 5 views
8

Ich versuche, den vollständigen ursprünglichen Text innerhalb einer Methode, die als LuisIntent innerhalb einer LuisDialog markiert ist, zuzugreifen.Wie gelangen Sie zum ursprünglichen Nachrichtentext in einem Microsoft Bot Framework LuisIntent-Methode

Die Dokumentation zeigt diese Methoden unter zwei Argumente:

IDialogContext context, LuisResult result 

Keiner von denen öffentlich den ursprünglichen Text der Nachricht aussetzt. Das Kontextobjekt enthält die Nachricht jedoch in einer privaten Eigenschaft (context.data.message.text), auf die nicht zugegriffen werden kann.

Gibt es eine Möglichkeit, auf diese in der context zuzugreifen, oder kann es in den Dialogkonstruktor übergeben werden?

+0

Hier gilt die gleiche Frage. – fdezjose

Antwort

5

Sie können die MessageReceived (...) Funktion des LuisDialog die Felder des halten außer Kraft setzen Nachricht, die Sie als Mitgliedsvariablen benötigen, und greifen Sie auf diese Felder in Ihren Intent-Handlern zu. Im Folgenden werde ich die SimpleAlarmDialog geändert zu zeigen, wie Sie ‚message.Text‘ in einer der Absicht Handler zugreifen:

[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); 
    } 
} 
+0

Auch wenn die Version 1.0.2 des Bot-Frameworks den Nachrichtentext hinzufügt, enthält sie dennoch nicht alle zusätzlichen Informationen, ConversationId usw., die im Nachrichtenobjekt des Controllers enthalten sind. Dadurch kann ich alle zusätzlichen Felder hinzufügen, die ich brauche. Vielen Dank! –

+1

Obwohl dies für V1 des Bot-Framework funktionierte, scheint es für V3 zu scheitern. Wenn Sie versuchen, die asynchrone Methode zu überschreiben, wird ein interner Serverfehler zurückgegeben, wenn die base.MessageReceived aufgerufen wird. –

1

Wenn Sie in die Methode einbrechen, können Sie in der Schnellübergabe sehen, dass das Kontextobjekt eine nicht öffentliche Eigenschaft hat bis hin zu context.data.mesage.Text (beachten Sie den Rechtschreibfehler von "message"). Da die Eigenschaft nicht-öffentlich ist, könnten Sie betrügen, indem mithilfe von Reflektion, um es zu bekommen (siehe 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; 
8

Mit der neuen Version von Bot Framework (1.0.2) die LuisResult Objekt jetzt eine hat Abfrage Parameter, der die ursprüngliche an LUIS gesendete Abfrage enthält.

0

Man könnte es so machen, indem Sie die Query-Eigenschaft des LuisResult verwenden,

[LuisIntent(intentName: "someIntentName")] 
private async Task Eligibility(IDialogContext context, LuisResult result) 
{ 
    await context.PostAsync($"The original text is: {result.Query}"); 
    context.Wait(MessageReceivedAsync); 
}