c# - bot框架中语言错误的主动本地化formflow的第一次提示
问题描述
我已将此作为错误报告提交,但也会在此处提交,以防我做错了什么,而这并不是真正的错误。
Bot框架版本
3.16.1.38846
描述问题
我正在尝试创建一个可以主动触发的本地化表单流。我能够创建表单并使用主动对话触发器通过 API 调用触发它。然而,第一个问题总是用英语,尽管语言环境不是英语。尽管如此,它还是希望在使用中的语言环境中得到答案(在这种情况下为普通话,(zh-SG))。
如果我不通过我的 API 触发它,我所有的问题都会根据我通过机器人框架模拟器发送的任何语言环境进行本地化。我通过在根对话框中设置关键字检查对此进行了测试,并且我能够以指定的语言询问我的所有表单流问题。我还附上了这似乎如何发挥作用的屏幕截图。
重现
重现行为的步骤:
- 创建一个简单的表格
- 使用文档中的指南本地化表单
- 使用机器人框架模拟器调用表单,并在根对话框中使用简单的关键字检查。使用 en-US 的默认语言环境(示例如下)
- 使用机器人框架模拟器调用表单,并在根对话框中使用简单的关键字检查。使用其他语言的区域设置(在本例中为 zh-SG)
- 通过 WebAPI 使用主动对话触发器调用表单。方法看起来像这样。活动对象等参数之前已序列化到数据库中。我隐藏了某些参数以保护某些机密信息
样本触发器
if (activity.Text.Equals("Trigger"))
{
var form = new FormDialog<Form1>(new Form1(), Form1.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formCompleteAsync);
}
WebAPI 方法
public IHttpActionResult Post([FromBody]Model Model)
{
if (ModelState.IsValid)
{
try
{
StartProactiveDialogAsync(model.someId, model.anotherId)
return Ok();
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
else
{
return BadRequest(ModelState);
}
}
启动主动对话异步
public async Task StartProactiveDialogAsync(someId, anotherId )
{
try
{
// Recreate the message from the conversation reference that was saved previously.
Activity activity = JsonConvert.DeserializeObject<Activity>(BotUserData.ConversationReference);
MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl);
var client = new ConnectorClient(new Uri(activity.ServiceUrl));
// Create a scope that can be used to work with state from bot framework.
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(CancellationToken.None);
// This is the dialog stack.
var stack = scope.Resolve<IDialogTask>();
// Create the new dialog and add it to the stack.
var dialog = new CallDialog(parameter1, parameter2);
stack.Call(dialog.Void<object, IMessageActivity>(), null);
await stack.PollAsync(CancellationToken.None);
// Flush the dialog stack back to its state store.
await botData.FlushAsync(CancellationToken.None);
}
}
catch (Exception e)
{
await ProprietaryDiagnosticsTool.SendDiagnostic(e);
}
}
呼叫对话
public class CallDialog : IDialog<object>
{
Parameter1 param1;
Parameter2 param2;
public CallDialog(Parameter1 param1, Parameter2 param2)
{
this.param1 = param1;
this.param2 = param2;
}
public async Task StartAsync(IDialogContext context)
{
switch (param1.Id)
{
case 1:
{
var form = new FormDialog<Form1>(new Form1(), Form1.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formComplete);
break;
}
case 2:
{
var form = new FormDialog<Form2>(new Form2(), Form2.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formComplete);
break;
}
case 3:
{
var form = new FormDialog<Form3>(new Form3(), Form3.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formComplete);
break;
}
}
}
private async Task formComplete(IDialogContext context, IAwaitable<FormParent> result)
{
var ans = await result;
await context.PostAsync("Result received");
context.Done(this);
}
}
预期行为
当调用在不同语言环境中调用表单的主动对话框时,表单应以指定的语言环境呈现
截图
错误消息说
“是”不是问题 1 的选项。
附加信息
我已经通过各种方法跟踪了 context.activity 对象,从 StartProactiveDialogAsync 到 CallDialog 一直到 formComplete 方法。语言环境确实往往是正确的,它只是显示主动对话框的第一个问题,调用恰好使用错误语言的表单流。
解决方案
来自 Microsoft 的 Eric 帮助解决了这个问题。
他的完整答案可以在这里找到:https ://github.com/Microsoft/BotBuilder-V3/issues/82
简单地说,需要将语言环境从 context.activity.privateconversationdata 中提取出来并发送到表单本身,因为它在恢复对话时不会自行选择语言环境。
推荐阅读
- database - postgresql 多租户模式与数据库
- apache-kafka - 无法消费或生产到远程 Kafka 代理
- npm - 电子安装错误:为“electron-v2.0.2-win32-x64.zip”生成的校验和与预期的校验和不匹配
- python - groupby 一列并计算另一个熊猫中超过 5 的项目
- mysql - 插入错误 #1452 - 无法添加或更新子行:外键约束失败
- java - 检测到新的指纹登记
- angular - 角材料日期选择器自定义格式
- anylogic - AnyLogic 如何将一个代理链接到另一个代理
- kubernetes - k8s DaemonSet:被拒绝的 Pod 重新创建太快而无法获取任何日志或事件
- javascript - NodeJS & express 使用 Promise 实现 HTTP 模块的 catch 写入功能