AdaptiveCards 在 .NET 解析期间引发异常
Posted
技术标签:
【中文标题】AdaptiveCards 在 .NET 解析期间引发异常【英文标题】:AdaptiveCards throws an exception during .NET parsing 【发布时间】:2021-11-14 05:25:55 【问题描述】:我目前在解析自适应卡片时遇到了以下问题。
这是卡片:
"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 在 text 属性中看起来不对:
"type":"AdaptiveCard","$schema":"http://adaptivecards.io/schemas/adaptive-card.json","version":"1.4","body":["type":"TextBlock","text":,"wrap":true]
我正在使用自适应卡 nuget 包:
AdaptiveCards 2.7.2 AdaptiveCards.Templating 1.2.我是否遇到了解析错误? text 属性的值应为 10.9.2021。
在adaptivecards.io 的设计器中,出于某种原因,一切正常。有没有人有修复/解决方法?
【问题讨论】:
在 cardJson 上生成的 JSON 肯定是格式错误的。将其上传到jsonformatter.curiousconcept.com 或jsonlint.com,您将收到"text": ,
缺少属性值的错误。所以问题不在于解析,而在于 JSON 生成。对于cardJson
中的"text"
的值,您期望得到什么?是"DATE(2021-09-10T16:29:59Z, COMPACT)"
吗?
@dbc 该值应为 10.9.2021。通常自适应卡片会在给定的上下文中呈现它。它适用于在线自适应卡片设计器 (adaptivecards.io),但不适用于 .Net
【参考方案1】:
如果您希望文字 "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
]
演示小提琴 #1 here.
如果您希望 "DATE(2021-09-10T16:29:59Z, COMPACT)"
在 cardJson
中使用 delegates date formatting to the TextBlock
,请使用:
"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)",
演示小提琴 #2 here.
注意事项:
根据Microsoft documentation:
使用点符号 来访问对象层次结构的子对象。例如,$myParent.myChild
使用索引器语法通过键或数组中的项检索属性。例如,$myArray[0]
但是,当访问名称中带有连字符(或其他一些reserved operator)的对象属性时,显然有必要使用索引器语法['DUE-DATE']
而不是点符号来检索其值,传递属性将单引号字符串中的名称作为索引器。
根据docs
有一些保留关键字可以访问各种绑定范围。 ...
"$root": "The root data object. Useful when iterating to escape to parent object",
因此,当使用点表示法访问当前作用域对象(默认情况下为根)的属性时,您不需要使用$root
。如果出于某种原因您需要或想要直接处理根对象,您可以使用$root
,如下所示:
"text": "$formatDateTime($root.AdditionalData['DUE-DATE'], 'd.M.yyyy')",
演示小提琴#3 here.
但是,似乎将$root
与DATE()
结合使用会导致生成格式错误的JSON。即
"text": "DATE($$root.AdditionalData['DUE-DATE'], COMPACT)",
结果为@987654356@,如您的问题所示。
演示小提琴#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)",
演示小提琴 #5 here.
来自文档页面Adaptive Card Templating SDKs: Troubleshooting:
问。为什么 RFC 3389 格式的日期/时间(例如“2017-02-14T06:08:00Z”与模板一起使用时不适用于 TIME/DATE 函数? A. .NET sdk nuget 版本 1.0.0-rc.0 表现出这种行为。此行为在后续版本中得到纠正...请使用 formatDateTime() 函数将日期/时间字符串格式化为 RFC 3389,如 this example 中所示,或者您可以绕过 TIME/DATE 函数,而只使用 formatDateTime()。有关formatDateTime()的更多信息,请转至here。
虽然使用 formatDateTime
的建议是为了解决 1.0.0-rc.0 中的问题,但该技巧也解决了上面注释 #2 中提到的问题。
【讨论】:
以上是关于AdaptiveCards 在 .NET 解析期间引发异常的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft Teams - 在聊天中呈现自适应卡片的问题
如何正确解析要在 ASP.NET Core 3.1 的 ConfigureServices() 中使用的服务?