Azure Bot问题:JSON载荷数据转自适应卡片的格式化难题
Azure Bot 问题解决方案
一、清理JSON响应中的特殊转义字符
不要用字符串replace硬编码处理,通过JSON解析+重新序列化是最可靠的方案,能自动处理标准转义:
C# 实现(Azure Bot 主流开发语言)
// 假设已获取到带转义的响应文本 var rawResponse = await httpClient.GetStringAsync(remoteEndpoint); // 反序列化为动态对象,自动解析转义 var parsedData = JsonConvert.DeserializeObject<dynamic>(rawResponse); // 重新序列化得到无冗余转义的JSON var cleanJson = JsonConvert.SerializeObject(parsedData);
Node.js 实现
const rawResponse = await fetch(remoteEndpoint).then(res => res.text()); const parsedData = JSON.parse(rawResponse); const cleanJson = JSON.stringify(parsedData);
如果是局部字段存在额外转义(比如嵌套字符串里的多余\),可针对字段单独处理:
// 示例:清理content字段中的多余转义 var cleanedContent = parsedData.content.ToString().Replace("\\", "");
二、自适应卡片遍历渲染修复
自适应卡片的foreach需严格遵循语法规范,核心要点如下:
1. 确保数据源为数组类型
你的返回JSON中必须包含可遍历的数组字段(比如userADInfos、groupList),否则遍历逻辑无法生效。
2. 正确的自适应卡片语法
使用$data属性绑定遍历逻辑,示例卡片结构:
{ "type": "AdaptiveCard", "version": "1.5", "body": [ { "type": "TextBlock", "text": "请求结果列表", "size": "Large", "weight": "Bolder" }, { "type": "Container", "$data": "{foreach item in root.targetArray}", "items": [ { "type": "TextBlock", "text": "*姓名*: {item.displayName}", "wrap": true }, { "type": "TextBlock", "text": "*邮箱*: {item.mail}", "isSubtle": true, "wrap": true }, { "type": "TextBlock", "text": "---", "size": "Small" } ] } ] }
注:将root.targetArray替换为你的实际数组字段名(比如root.userADInfos)。
3. Bot代码中绑定数据源
在Bot逻辑中,将解析后的数组数据传入卡片:
// 加载自适应卡片模板(可从JSON文件读取或硬编码) var adaptiveCard = AdaptiveCard.FromJson(cardJson).Card; // 创建附件并绑定数据源 var cardAttachment = new Attachment { ContentType = AdaptiveCard.ContentType, Content = adaptiveCard, Data = new { targetArray = parsedData.userADInfos } }; // 将卡片发送给用户 await turnContext.SendActivityAsync(MessageFactory.Attachment(cardAttachment), cancellationToken);
4. 动态适配不同请求类型
由于你的请求类型(获取AD信息、设置组等)返回结构不同,可通过判断请求标识,加载对应的卡片模板:
string cardTemplatePath = requestType switch { "GetADUser" => "./Templates/GetADUserCard.json", "SetAzureADGroup" => "./Templates/SetGroupCard.json", _ => "./Templates/DefaultCard.json" }; var cardJson = File.ReadAllText(cardTemplatePath);
内容的提问来源于stack exchange,提问作者JDoeHera
相关产品推荐
相关产品推荐

