如何处理Context.Done(R值)
How to deal with Context.Done(R value)
我有一个 msbot 聊天对话框,我希望它具有以下行为:
user -> get me some info about GARY
bot -> which gary, (prompt: choice options)
user -> gary peskett
bot -> sure, (hero card with gary's contact details)
我有这个代码
public class CustomerRepository
{
private IList<Customer> _customerList = new List<Customer>
{
new Customer
{
Name = "Gary Peskett"
},
new Customer
{
Name = "Gary Richards"
},
new Customer
{
Name = "Barry White"
}
};
public async Task<IEnumerable<Customer>> GetAll()
{
// usually calls a database (which is why async is on this method)
return _customerList;
}
}
public class XDialog : IDialog
{
private readonly IIntent _intent;
private readonly CustomerRepository _customerRepository;
public XDialog(IIntent intent, CustomerRepository customerRepository)
{
// An intent is decided before this point
_intent = intent;
_customerRepository = customerRepository;
}
public async Task StartAsync(IDialogContext context)
{
// // An intent can provide parameters
string name = _intent.Parameters["Name"] as string;
IEnumerable<Customer> customers = await _customerRepository.GetAll();
IList<Customer> limitedList = customers.Where(x => x.Name.Contains(name)).ToList();
if (limitedList.Any())
{
if (limitedList.Count > 1)
{
PromptDialog.Choice(context, LimitListAgain, limitedList,
"Can you specify which customer you wanted?");
}
else
{
Customer customer = limitedList.FirstOrDefault();
Finish(context, customer);
}
}
else
{
context.Done("No customers have been found");
}
}
private static async Task LimitListAgain(IDialogContext context, IAwaitable<Customer> result)
{
Customer customer = await result;
Finish(context, customer);
}
private static void Finish(IDialogContext context, Customer customer)
{
HeroCard heroCard = new HeroCard
{
Title = customer?.Name
};
context.Done(heroCard);
}
}
我发现通常当我执行 context.Done(STRING) 时,它会输出给用户,这对于结束对话非常有用。因为我想以一张英雄卡结束,它输出类型名
Microsoft.Bot.Connector.HeroCard
谁能帮忙解释一下使用 context.Done(R 值)的更好方法,或者帮我 return 一张英雄卡来结束对话?
正在使用
调用对话框
Chain.PostToChain()
.Select(msg => Task.Run(() => _intentionService.Get(msg.ChannelId, msg.From.Id, msg.Text)).Result)
.Select(intent => _actionDialogFactory.Create(intent)) // returns IDialog based on intent
.Unwrap()
.PostToUser();
我认为问题是使用 Chain
的副作用。
如您所知,context.Done
不会 post 返回给用户任何东西,它只是使用提供的值结束当前对话框。
给用户的 post 实际上发生在 Chain
末尾的 .PostToUser()
中。现在,通过查看 PostToUser's code, I realized that at the end of the game, it's doing a context.PostAsync
of item.ToString()
, being item the payload provided in the context.Done
in this case. See this.
一个选项(我还没有测试过),可以使用 .Do
而不是 .PostToUser()
并手动执行 PostToUserDialog 所做的,最后执行 context.PostAsync() 通过创建一个新的 IMessageActivity
并将 HeroCard
添加为附件。
我有一个 msbot 聊天对话框,我希望它具有以下行为:
user -> get me some info about GARY
bot -> which gary, (prompt: choice options)
user -> gary peskett
bot -> sure, (hero card with gary's contact details)
我有这个代码
public class CustomerRepository
{
private IList<Customer> _customerList = new List<Customer>
{
new Customer
{
Name = "Gary Peskett"
},
new Customer
{
Name = "Gary Richards"
},
new Customer
{
Name = "Barry White"
}
};
public async Task<IEnumerable<Customer>> GetAll()
{
// usually calls a database (which is why async is on this method)
return _customerList;
}
}
public class XDialog : IDialog
{
private readonly IIntent _intent;
private readonly CustomerRepository _customerRepository;
public XDialog(IIntent intent, CustomerRepository customerRepository)
{
// An intent is decided before this point
_intent = intent;
_customerRepository = customerRepository;
}
public async Task StartAsync(IDialogContext context)
{
// // An intent can provide parameters
string name = _intent.Parameters["Name"] as string;
IEnumerable<Customer> customers = await _customerRepository.GetAll();
IList<Customer> limitedList = customers.Where(x => x.Name.Contains(name)).ToList();
if (limitedList.Any())
{
if (limitedList.Count > 1)
{
PromptDialog.Choice(context, LimitListAgain, limitedList,
"Can you specify which customer you wanted?");
}
else
{
Customer customer = limitedList.FirstOrDefault();
Finish(context, customer);
}
}
else
{
context.Done("No customers have been found");
}
}
private static async Task LimitListAgain(IDialogContext context, IAwaitable<Customer> result)
{
Customer customer = await result;
Finish(context, customer);
}
private static void Finish(IDialogContext context, Customer customer)
{
HeroCard heroCard = new HeroCard
{
Title = customer?.Name
};
context.Done(heroCard);
}
}
我发现通常当我执行 context.Done(STRING) 时,它会输出给用户,这对于结束对话非常有用。因为我想以一张英雄卡结束,它输出类型名
Microsoft.Bot.Connector.HeroCard
谁能帮忙解释一下使用 context.Done(R 值)的更好方法,或者帮我 return 一张英雄卡来结束对话?
正在使用
调用对话框Chain.PostToChain()
.Select(msg => Task.Run(() => _intentionService.Get(msg.ChannelId, msg.From.Id, msg.Text)).Result)
.Select(intent => _actionDialogFactory.Create(intent)) // returns IDialog based on intent
.Unwrap()
.PostToUser();
我认为问题是使用 Chain
的副作用。
如您所知,context.Done
不会 post 返回给用户任何东西,它只是使用提供的值结束当前对话框。
给用户的 post 实际上发生在 Chain
末尾的 .PostToUser()
中。现在,通过查看 PostToUser's code, I realized that at the end of the game, it's doing a context.PostAsync
of item.ToString()
, being item the payload provided in the context.Done
in this case. See this.
一个选项(我还没有测试过),可以使用 .Do
而不是 .PostToUser()
并手动执行 PostToUserDialog 所做的,最后执行 context.PostAsync() 通过创建一个新的 IMessageActivity
并将 HeroCard
添加为附件。