首页 > 解决方案 > bot框架中语言错误的主动本地化formflow的第一次提示

问题描述

我已将此作为错误报告提交,但也会在此处提交,以防我做错了什么,而这并不是真正的错误。

Bot框架版本

3.16.1.38846

描述问题

我正在尝试创建一个可以主动触发的本地化表单流。我能够创建表单并使用主动对话触发器通过 API 调用触发它。然而,第一个问题总是用英语,尽管语言环境不是英语。尽管如此,它还是希望在使用中的语言环境中得到答案(在这种情况下为普通话,(zh-SG))。

如果我不通过我的 API 触发它,我所有的问题都会根据我通过机器人框架模拟器发送的任何语言环境进行本地化。我通过在根对话框中设置关键字检查对此进行了测试,并且我能够以指定的语言询问我的所有表单流问题。我还附上了这似乎如何发挥作用的屏幕截图。

重现

重现行为的步骤:

  1. 创建一个简单的表格
  2. 使用文档中的指南本地化表单
  3. 使用机器人框架模拟器调用表单,并在根对话框中使用简单的关键字检查。使用 en-US 的默认语言环境(示例如下)
  4. 使用机器人框架模拟器调用表单,并在根对话框中使用简单的关键字检查。使用其他语言的区域设置(在本例中为 zh-SG)
  5. 通过 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);
    }
}

预期行为

当调用在不同语言环境中调用表单的主动对话框时,表单应以指定的语言环境呈现

截图

通过关键字触发的英文formflow - 正确 通过关键字触发的英文formflow

通过 API 触发的英文表单流 - 正确 通过 API 触发的英文 formflow

通过关键字触发的普通话表单流 - 正确 通过关键字触发的普通话formflow

通过 API 触发的普通话表单流 - 不正确 通过 API 触发的普通话 formflow

错误消息说

“是”不是问题 1 的选项。

附加信息

我已经通过各种方法跟踪了 context.activity 对象,从 StartProactiveDialogAsync 到 CallDialog 一直到 formComplete 方法。语言环境确实往往是正确的,它只是显示主动对话框的第一个问题,调用恰好使用错误语言的表单流。

标签: c#botframework

解决方案


来自 Microsoft 的 Eric 帮助解决了这个问题。

他的完整答案可以在这里找到:https ://github.com/Microsoft/BotBuilder-V3/issues/82

简单地说,需要将语言环境从 context.activity.privateconversationdata 中提取出来并发送到表单本身,因为它在恢复对话时不会自行选择语言环境。


推荐阅读