C# 带着路易斯的意图

C# 带着路易斯的意图,c#,botframework,azure-language-understanding,C#,Botframework,Azure Language Understanding,所以他们在EchoBot示例中有一个很好的示例来演示链 public static readonly IDialog<string> dialog = Chain.PostToChain() .Select(msg => msg.Text) .Switch( new Case<string, IDialog<string>>(text => {

所以他们在EchoBot示例中有一个很好的示例来演示链

 public static readonly IDialog<string> dialog = Chain.PostToChain()
        .Select(msg => msg.Text)
        .Switch(
            new Case<string, IDialog<string>>(text =>
                {
                    var regex = new Regex("^reset");
                    return regex.Match(text).Success;
                }, (context, txt) =>
                {
                    return Chain.From(() => new PromptDialog.PromptConfirm("Are you sure you want to reset the count?",
                    "Didn't get that!", 3)).ContinueWith<bool, string>(async (ctx, res) =>
                    {
                        string reply;
                        if (await res)
                        {
                            ctx.UserData.SetValue("count", 0);
                            reply = "Reset count.";
                        }
                        else
                        {
                            reply = "Did not reset count.";
                        }
                        return Chain.Return(reply);
                    });
                }),
            new RegexCase<IDialog<string>>(new Regex("^help", RegexOptions.IgnoreCase), (context, txt) =>
                {
                    return Chain.Return("I am a simple echo dialog with a counter! Reset my counter by typing \"reset\"!");
                }),
            new DefaultCase<string, IDialog<string>>((context, txt) =>
                {
                    int count;
                    context.UserData.TryGetValue("count", out count);
                    context.UserData.SetValue("count", ++count);
                    string reply = string.Format("{0}: You said {1}", count, txt);
                    return Chain.Return(reply);
                }))
        .Unwrap()
        .PostToUser();
}
public static readonly IDialog=Chain.PostToChain()
.Select(msg=>msg.Text)
.开关(
新案例(文本=>
{
var regex=新的regex(“^reset”);
返回regex.Match(text.Success);
},(上下文,txt)=>
{
返回链。从(()=>新建PromptDialog.PromptConfirm(“是否确实要重置计数?”),
“没有得到它!”,3)).ContinueWith(异步(ctx,res)=>
{
字符串回复;
如果(等待res)
{
ctx.UserData.SetValue(“计数”,0);
答复=“重置计数。”;
}
其他的
{
答复=“未重置计数。”;
}
返回链。返回(回复);
});
}),
新建RegexCase(新建Regex(“^help”,RegexOptions.IgnoreCase),(上下文,txt)=>
{
return Chain.return(“我是一个带有计数器的简单回显对话框!通过键入“Reset\”!)重置我的计数器”;
}),
新的DefaultCase((上下文,txt)=>
{
整数计数;
context.UserData.TryGetValue(“count”,out count);
context.UserData.SetValue(“计数”++count);
string reply=string.Format(“{0}:您说的是{1}”,count,txt);
返回链。返回(回复);
}))
.Unwrap()
.PostToUser();
}
然而,与其使用正则表达式来确定我的对话路径,我更愿意使用路易斯意图。我正在使用这段漂亮的代码来提取路易斯的意图

public static async Task<LUISQuery> ParseUserInput(string strInput)
    {
        string strRet = string.Empty;
        string strEscaped = Uri.EscapeDataString(strInput);

        using (var client = new HttpClient())
        {
            string uri = Constants.Keys.LUISQueryUrl + strEscaped;
            HttpResponseMessage msg = await client.GetAsync(uri);

            if (msg.IsSuccessStatusCode)
            {
                var jsonResponse = await msg.Content.ReadAsStringAsync();
                var _Data = JsonConvert.DeserializeObject<LUISQuery>(jsonResponse);
                return _Data;
            }
        }
        return null;
    }
公共静态异步任务ParseUserInput(字符串strInput)
{
string strRet=string.Empty;
string strEscaped=Uri.EscapeDataString(strInput);
使用(var client=new HttpClient())
{
字符串uri=Constants.Keys.luiskryURL+strEscaped;
HttpResponseMessage msg=await client.GetAsync(uri);
if(消息IsSuccessStatusCode)
{
var jsonResponse=await msg.Content.ReadAsStringAsync();
var _Data=JsonConvert.DeserializeObject(jsonResponse);
返回数据;
}
}
返回null;
}

不幸的是,因为这是异步的,所以运行case语句时不能很好地使用LINQ查询。有谁能给我提供一些代码,让我能够根据路易斯的意图在我的链中有一个案例陈述吗?

Omg的评论是正确的

请记住,IDialog有一个类型,这意味着IDialog可以返回自己指定类型的对象:

public class TodoItemDialog : IDialog<TodoItem>
{
   // Somewhere, you'll call this to end the dialog
   public async Task FinishAsync(IDialogContext context, IMessageActivity activity)
   {
      var todoItem = _itemRepository.GetItemByTitle(activity.Text);
      context.Done(todoItem);
   }
}
公共类TodoItemDialog:IDialog
{
//在某个地方,您可以调用此来结束对话框
公共异步任务完成同步(IDialogContext上下文,IMessageActivity活动)
{
var todoItem=\u itemRepository.GetItemByTitle(activity.Text);
上下文。完成(todoItem);
}
}
调用context.Done()返回对话框要返回的对象。当你阅读任何类型的IDialog的类声明时

public class TodoItemDialog : LuisDialog<TodoItem>
公共类TodoItemDialog:LuisDialog 将其解读为:

“TodoItemDialog是一个对话框类,完成后返回TodoItem”

您可以使用context.Forward()来代替链接,它基本上将相同的messageActivity转发给另一个对话类

context.Forward()context.Call()之间的区别主要在于context.Forward()允许您转发消息活动,该活动由调用的对话框立即处理,而context.Call()只启动一个新对话框,而无需移交任何内容

在“根”对话框中,如果需要使用LUIS确定意图并返回特定对象,只需使用forward将messageActivity转发给它,然后在指定的回调中处理结果:

await context.Forward(new TodoItemDialog(), AfterTodoItemDialogAsync, messageActivity, CancellationToken.None);

private async Task AfterTodoItemDialogAsync(IDialogContext context, IAwaitable<TodoItem> result)
{
    var receivedTodoItem = await result;

    // Continue conversation
}
wait context.Forward(新的TodoItemDialog()、AfterDoItemDialogAsync、messageActivity、CancellationToken.None);
私有异步任务AfterdoItemDialogAsync(IDialogContext上下文,IAwaitable结果)
{
var receivedTodoItem=等待结果;
//继续对话
}
最后,您的LuisDialog类可以如下所示:

[Serializable, LuisModel("[ModelID]", "[SubscriptionKey]")]
public class TodoItemDialog : LuisDialog<TodoItem>
{
    [LuisIntent("GetTodoItem")]
    public async Task GetTodoItem(IDialogContext context, LuisResult result)
    {
        await context.PostAsync("Working on it, give me a moment...");
        result.TryFindEntity("TodoItemText", out EntityRecommendation entity);
        if(entity.Score > 0.9)
        {
            var todoItem = _todoItemRepository.GetByText(entity.Entity);
            context.Done(todoItem);
        }
    }
}
[Serializable,LuisModel(“[ModelID]”,“[SubscriptionKey]”)
公共类TodoItemDialog:LuisDialog
{
[LuisIntent(“GetTodoItem”)]
公共异步任务GetTodoItem(IDialogContext上下文,LuisResult结果)
{
等待上下文。PostAsync(“正在处理它,给我一点时间…”);
结果.tryFindential(“TodoItemText”,out EntityRecommendation entity);
如果(实体分数>0.9)
{
var todoItem=\u todoItemRepository.GetByText(entity.entity);
上下文。完成(todoItem);
}
}
}

(为了简洁起见,我在示例中没有其他语句,这当然是您需要添加的)

为什么不使用context.call和context.Forward来链接对话框(在对话框内部),而不是在bot框架中使用“chain dialog”?