将数组数据存储在卡中的简单示例

2024-03-30

我想了解如何使用自适应卡读取/写入数据。我可以从提交操作中读取数据,并以文本形式回复,但不确定如何在卡中呈现输入数据。首先,我想将 shotValue 添加到一个数组中,我可以在卡的生命周期中携带该数组。有人可以让我知道该怎么做吗?

此问题的目标是了解如何保留卡片的现有响应。 就像在《战舰》中一样,我拍摄“A1”,在输入框中键入它,然后提交,我希望在卡片中看到“A1”。我添加“A2”,提交,然后我希望在发送到 Teams 的卡片中看到“A1”和“A2”。我知道我需要在每次拍摄时从头开始重建卡片,这意味着我需要在每个动作中以某种方式继续拍摄。

数据卡:

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "Hello {name}"
    },
    {
      "type": "ColumnSet",
      "columns": [
        {
          "type": "Column",
          "width": "stretch",
          "id": "",
          "items": [
            {
              "type": "Container",
              "items": [
                {
                  "type": "Input.Text",
                  "placeholder": "Voorbeeld: A1",
                  "id": "id_shoot",
                  "$data": "shoot"
                }
              ]
            }
          ]
        },
        {
          "type": "Column",
          "width": "stretch",
          "items": [
            {
              "type": "Container",
              "items": [
                {
                  "type": "TextBlock",
                  "text": " {shoot}",
                  "horizontalAlignment": "Right",
                  "id": ""
                }
              ],
              "$data": "{shoots}",
              "id": "shotcoords"
            }
          ],
          "$data": "{shots}"
        },
        {
          "type": "Column",
          "width": "stretch",
          "items": [
            {
              "type": "Container",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "{status}",
                  "id": ""
                }
              ],
              "$data": "{shoots}",
              "id": "shotstatuses"
            }
          ],
          "id": ""
        }
      ]
    },
    {
      "type": "ActionSet",
      "id": "",
      "actions": [
        {
          "type": "Action.Submit",
          "title": "Shoot",
          "id": "",
          "style": "positive",
          "data": {}
        }
      ]
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}

Data

{
  "name": "Test shot",
  "shoots": [
    {
      "shoot": "a1",
      "status": "hit"
    },
    {
      "shoot": "a2",
      "status": "hit"
    }
  ]
}

没有“简单”的方法可以做到这一点,但有一种方法。答案将类似于this one https://stackoverflow.com/a/57418517/2122672.

首先,您需要一种保存卡状态的方法,以便可以更新卡的活动。在 C# 中,您可以像这样声明状态属性访问器:

public IStatePropertyAccessor<Dictionary<string, (string ActivityId, List<string> Shots)>> BattleshipStateAccessor { get; internal set; }

然后你可以像这样实例化它

BattleshipStateAccessor = _conversationState.CreateProperty<Dictionary<string, (string, List<string>)>>("battleshipState");

您需要在这里做出一些决定。首先,我选择将状态属性设置为字典,以便我可以跟踪多张卡片并仅更新单击的特定卡片。如果您不关心这一点,那么您不需要字典,也不需要担心“卡 ID”,但至少需要保存一个活动 ID,以便您能够更新卡。至于保存“镜头”,您有几个选择。您可以通过在每次拍摄时更新提交操作的数据来在客户端保存该状态,但我认为我也可以将拍摄保存在机器人状态中,因为无论如何我已经需要将活动 ID 保存在机器人状态中。接下来的问题是您应该保存每个镜头的哪些信息。在这个例子中,我只保存用户输入的镜头位置,而不是镜头状态,因为我认为我可以在需要时随时重新计算状态。

我已将您的提交操作修改为如下所示:

{
  "type": "Action.Submit",
  "title": "Shoot",
  "style": "positive",
  "data": {
    "behavior": "Shoot",
    "cardId": ""
  }
}

我在这里所做的是将两个属性添加到您的数据对象,并且该数据将与文本输入的值一起发送到您的机器人。如果您的机器人使用可以以不同方式处理的多种类型的操作,“行为”属性将帮助您的机器人路由到正确的功能。 “cardId”属性只是一个占位符,您的机器人代码将在创建卡片时填充该占位符。我已将这些属性的名称存储在常量中KEYBEHAVIOR and KEYCARDID.

您需要采用一致的方式来生成卡片,以便在最初发送卡片和更新卡片时使用。

internal static IMessageActivity CreateBattleshipCardActivity(
    string cardId,
    object data = null)
{
    data = data ?? new
    {
        name = "Test shot",
        shoots = new string[0],
    };

    JObject card = CreateAdaptiveCard("battleship", data);

    foreach (var token in card.Descendants()
        .Select(token => token as JProperty)
        .Where(token => token?.Name == KEYCARDID))
    {
        token.Value = cardId;
    }

    return MessageFactory.Attachment(new Attachment(
        AdaptiveCard.ContentType,
        content: card));
}

The CreateAdaptiveCard函数从具有给定名称的文件加载 JSON 模板,使用给定数据对其进行转换,并将其反序列化为JObject.

使用此函数,您可以在 C# 中像这样最初发送卡片:

public async Task TestBattleshipAsync(
    ITurnContext turnContext,
    CancellationToken cancellationToken)
{
    var activity = turnContext.Activity;
    var cardId = Guid.NewGuid().ToString();
    var reply = CreateBattleshipCardActivity(cardId);
    var response = await turnContext.SendActivityAsync(reply, cancellationToken);
    var dict = await BattleshipStateAccessor.GetAsync(
        turnContext,
        () => new Dictionary<string, (string, List<string>)>(),
        cancellationToken);

    dict[cardId] = (response.Id, new List<string>());
}

您可以更新卡以响应卡的“拍摄”提交操作,如下所示:

private async Task ShootAsync(
    ITurnContext turnContext,
    CancellationToken cancellationToken)
{
    var activity = turnContext.Activity;

    if (activity.ChannelId == Channels.Msteams)
    {
        var value = JObject.FromObject(activity.Value);
        var cardId = Convert.ToString(value[BotUtil.KEYCARDID]);
        var dict = await BattleshipStateAccessor.GetAsync(
            turnContext,
            () => new Dictionary<string, (string, List<string>)>(),
            cancellationToken);

        if (dict.TryGetValue(cardId, out var savedInfo))
        {
            savedInfo.Shots.Add(value["id_shoot"].ToString());

            var data = new
            {
                name = "Test shot",
                shoots = savedInfo.Shots.Select(shot => new
                {
                    shoot = shot,
                    status = DetermineHit(shot),
                }),
            };

            var update = CreateBattleshipCardActivity(cardId, data);

            update.Id = savedInfo.ActivityId;
            update.Conversation = activity.Conversation;

            await turnContext.UpdateActivityAsync(update, cancellationToken);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将数组数据存储在卡中的简单示例 的相关文章

随机推荐

  • 在透明像素之上使用 DrawString 进行错误的文本渲染

    将文本渲染到位图时 我发现在具有非不透明 Alpha 的区域顶部渲染时 文本看起来非常糟糕 随着底层像素变得更加透明 问题变得越来越严重 如果我不得不猜测 我会说当底层像素是透明的时 文本渲染器将任何抗锯齿 灰色 像素绘制为纯黑色 以下是一
  • 强制 Microsoft Build Tools 2015 包含框架目标版本的 mscorlib,而不是 4.6

    我在 Visual Studio 2015 中编写了一个应用程序 它使用 C 6 0 功能并面向 NET 4 5 2 当我使用 Microsoft Build Tools 2015 构建它时 这是由我们的 TeamCity 服务器完成的 生
  • 日历视图突出显示错误的星期

    我的应用程序中有一个 CalendarView 当用户通过触摸月视图中的日期来选择日期时 会选择正确的日期 通过在代码中添加调试语句进行验证 但前一周会突出显示 所以看起来好像选择了错误的日期 我找到了一个解决方法 如果我将 firstDa
  • CallLog.Calls 处的 RuntimeException

    如果我尝试查询 有时在某些设备上会出现 RuntimeExceptionCallLog Calls 我查询的是CallLog Calls with contentProvider接听最后一个电话 有人可以帮助我为什么有时会出现此错误吗 我认
  • 从所有 WooCommerce 预订中获取所有人的总和

    我使用官方 woocommerce 预订插件 并尝试获取所有已预订产品的人员的数量 对于单个订单 没有问题 if is callable WC booking Data Store get booking ids from order id
  • 如何在iPhone中的plist中写入多个数组?

    我的应用程序中有十个数组 我想将这些数组值写入 文档目录 plist 是否可以将 10 个数组放入一个 plist 中 否则我将为每个数组创建单独的 plist 哪一个可以实现我的应用程序 请指导我并提供一些示例链接 Thanks 做你想做
  • 为什么c 库和语言定义_name,然后typedef 或pound 定义_name name?

    看来 C 库和语言有很多无用的类型名称 例如 C 有一个内置类型 Bool并且有一个宏stdbool h define bool Bool 为什么 C 没有bool内置而不是 Bool 我发现了更多的例子stdio h and stdlib
  • 使用 jquery 和 mvc razor 的 delimitir 问题

    我无法向同一字段添加几个值 我只能选择一个值 输入后 或其他分隔符 我无法选择另一个 我希望它的工作方式类似于自动完成 我有一个带有 jQ uery 绑定的文本框 div class editor field Html EditorFor
  • 打包应用程序时如何排除不必要的Qt *.so 文件?

    使用 PyInstaller 成功打包 PySide 应用程序后 我在包文件夹中发现了许多不同的 so 文件 我很惊讶地看到我在项目中没有使用的库 例如 libQt53DAnimation so libQt53DCore so libQt5
  • mysql中按月和年比较日期

    我有一个表 其中包含有关事件和节日的数据 并以下列记录其开始和结束日期 开始日期 End Date 日期格式为YYYY MM DD 我需要使用以下条件获取事件详细信息 需要获取以当前月份开始且结束日期可以是任何内容的所有事件currentD
  • 扩展访问表达式以检查值

    我目前正在尝试与表达式树进行斗争 以实现一些神奇的效果 但我不断遇到一个又一个的错误 我的一些域对象 实体框架 上有一些类似的属性 Expression
  • ZIO:如何只计算一次?

    我正在使用 ZIO https github com zio zio https github com zio zio in my build sbt dev zio zio 1 0 0 RC9 无论我尝试什么 每次需要时都会计算我的结果
  • C# Windows 窗体 - MenuItem 单击事件 - 获取 MenuItem 文本

    如何获取已单击的任何给定菜单项的文本 菜单是动态填充的 所以我似乎仅限于此 Menu MenuItems Add new MenuItem MenuName new EventHandler menu click 不幸的是 我看不到 Eve
  • Jenkins 在 Docker 容器内构建并生成报告

    我对 Jenkins 和 Docker 很陌生 即使经过一些研究 我也没有找到做这些事情的方法 我想要 在 docker 容器内的项目上执行 pytest 和 python coverage 这应该生成测试和覆盖率报告 访问生成的报告并使用
  • Chrome 下数字签名小程序的替代方案

    目前我们已经开发了一个可以使用java applet 对文档进行数字签名的系统 然而 随着 Chrome 下小程序的禁令 我们正在寻找数字签名的替代解决方案 目前签名的工作方式如下 HTTP GET 被发送到 servlet 以获取要发送的
  • Grails,使用会话中的值注入/填充域对象

    在我的应用程序中 许多类都有公共字段 公司 当应用程序保存该对象时 它们必须填写公司 对此进行了验证 公司也开会 现在 当我想使用域类作为命令对象时 公司必须已填写 否则我会收到验证错误 有什么方法可以在进行任何验证之前始终填写公司字段 这
  • 如何对时间轴上放置的点的值进行插值?

    我想创建不同位置 x 浓度随时间变化的插值图 如果可能的话 我想水平插值点 即随着时间的推移 以便为每个样本获得平滑的变色水平线 df lt data frame Concentration rnorm 30 Position rep c
  • jconn4.jar 的 Maven 存储库是什么?

    jConn3 是我唯一能找到的 com sybase jdbc3 jdbc jconn3 6 05 我的研究告诉我 jconn3 jar 和 jconn4 jar 是 Sybase jConnect 的一部分 为了下载 至少 最新版本的 j
  • “dat”协议能否有效支持视频直播?

    我希望能够通过以下方式实时流式传输视频 或任何其他大型且不断修改 附加的文件 dat Here https github com beakerbrowser webdb performance它说 dat 协议不支持文件级别的部分更新 这意
  • 将数组数据存储在卡中的简单示例

    我想了解如何使用自适应卡读取 写入数据 我可以从提交操作中读取数据 并以文本形式回复 但不确定如何在卡中呈现输入数据 首先 我想将 shotValue 添加到一个数组中 我可以在卡的生命周期中携带该数组 有人可以让我知道该怎么做吗 此问题的