AdaptiveCards 在 .NET 解析期间抛出异常

AdaptiveCards throws an exception during .NET parsing

我目前在解析自适应卡时遇到以下问题。

这是卡片:

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "body": [
        {
            "type": "TextBlock",
            "text": "{{DATE(${$root.AdditionalData['DUE-DATE']},COMPACT)}}",
            "wrap": true
        }
    ]
}

这是卡片内容:

{
    "AdditionalData": {
      "DUE-DATE": "2021-09-10T16:29:59Z"
    }
}

代码: c# on .NET Framework 4.7.2 其中 layout 是带有上述卡片的字符串,content 是带有上述卡片内容的字符串:

 AdaptiveCardTemplate template = new AdaptiveCardTemplate(layout);
 string cardJson = template.Expand(content);

 AdaptiveCardParseResult card = AdaptiveCard.FromJson(cardJson);

它崩溃了:

AdaptiveCards.AdaptiveSerializationException: 'Error reading string. Unexpected token: Undefined. Path 'text', line 1, position 137.'
JsonReaderException: Error reading string. Unexpected token: Undefined. Path 'text', line 1, position 137.

cardJson 上生成的 JSON 在文本 属性:

中对我来说看起来是错误的
{"type":"AdaptiveCard","$schema":"http://adaptivecards.io/schemas/adaptive-card.json","version":"1.4","body":[{"type":"TextBlock","text":,"wrap":true}]}

我正在使用自适应卡 nuget 包:

我遇到解析错误了吗?文本 属性 的值应为 10.9.2021.

在 adaptivecards.io 的设计器中,出于某种原因一切正常。有人有 fix/workaround 吗?

如果您希望文字 "text":"10.9.2021" 出现在您的 cardJson 中,请使用 "${formatDateTime(AdditionalData['DUE-DATE'], 'd.M.yyyy')}" 为您的 TextBlock 生成所需的值:

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4",
  "body": [
    {
      "type": "TextBlock",
      "text": "${formatDateTime(AdditionalData['DUE-DATE'], 'd.M.yyyy')}",
      "wrap": true
    }
  ]
}

这会导致 AdaptiveCardTemplate 执行所有日期格式并导致:

{
   "type":"AdaptiveCard",
   "$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
   "version":"1.4",
   "body":[
      {
         "type":"TextBlock",
         "text":"10.9.2021",
         "wrap":true
      }
   ]
}

演示 fiddle #1 here.

如果您希望 cardJsondelegates date formatting to the TextBlock 中的 "{{DATE(2021-09-10T16:29:59Z, COMPACT)}}",请使用:

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4",
  "body": [
    {
      "type": "TextBlock",
      "text": "{{DATE(${AdditionalData['DUE-DATE']}, COMPACT)}}",
      "wrap": true
    }
  ]
}

结果是

      "text": "{{DATE(2021-09-10T16:29:59Z, COMPACT)}}",

演示 fiddle #2 here.

备注:

  1. 根据Microsoft documentation:

    • Use Dot-notation to access sub-objects of an object hierarchy. E.g., ${myParent.myChild}
    • Use Indexer syntax to retrieve properties by key or items in an array. E.g., ${myArray[0]}

    但是,当访问名称中带有连字符(或其他一些 reserved operator)的对象 属性 时,显然有必要使用索引器语法 ['DUE-DATE'] 而不是点‑ 用于检索其值的符号,将 属性 名称作为索引器传递到单引号字符串中。

  2. 根据docs

    There are a few reserved keywords to access various binding scopes. ...

    "$root": "The root data object. Useful when iterating to escape to parent object",
    

    因此,在使用点表示法访问当前作用域对象(默认情况下为根)的属性时,无需使用 $root。如果出于某种原因您需要或想要直接寻址根对象,您可以像这样使用 $root

    "text": "${formatDateTime($root.AdditionalData['DUE-DATE'], 'd.M.yyyy')}",
    

    演示 fiddle #3 here.

    但是,似乎将 $root{{DATE()}} 结合使用会导致生成格式错误的 JSON。即

      "text": "{{DATE(${$root.AdditionalData['DUE-DATE']}, COMPACT)}}",
    

    如您的问题所示 "text":, 结果。

    演示 fiddle #4 here.

    这看起来是框架中的错误。可能是解析器阻塞了标记序列 ${$,因为您的问题有点类似于 Issue #6026: [Authoring][.NET][Templating] Inconsistency in accessing $root inside a $when property in adaptive card templating,它报告无法正确解析 "$when": "${$root.UserName != null}"

    您可以通过完全省略 $root 或将 $root.AdditionalData['DUE-DATE'] 包裹在额外的 formatDateTime() 中来避免此问题,如下所示:

       "text": "{{DATE(${formatDateTime($root.AdditionalData['DUE-DATE'])}, COMPACT)}}",
    

    导致

       "text": "{{DATE(2021-09-10T16:29:59.000Z, COMPACT)}}",
    

    演示 fiddle #5 here.

  3. 来自文档页面 Adaptive Card Templating SDKs: Troubleshooting:

    Q. Why date/time in RFC 3389 format e.g "2017-02-14T06:08:00Z" when used with template doesn't works with TIME/DATE functions?
    A. .NET sdk nuget version 1.0.0-rc.0 exhibits this behavior. this behavior is corrected in the subsequent releases... Please use formatDateTime() function to format the date/time string to RFC 3389 as seen in this example, or you can bypass TIME/DATE functions, and just use formatDateTime(). For more information on formatDateTime(), please go here.

    虽然这个使用 formatDateTime 的建议是为了修复 1.0.0-rc.0 中的一个问题,但这个技巧也解决了上面注释 #2 中提到的问题。