Azure Logic Apps中Compose与If块验证JSON属性存在性问题
Azure Logic App 条件判断失效问题排查与解决
需求背景
需要从以下JSON数据中提取email、first name、last name字段,组合成新的JSON对象:
{ "email": "donald.duck@waltdisney.com", "phone number": "+123 321 111 333", "fields": [ { "description": "name", "value": "Mickey", "id": 1 }, { "description": "first name", "value": "Donald", "id": 1 }, { "description": "last name", "value": "Duck", "id": 3 }, { "description": "age", "value": "1", "id": 4 } ] }
当前采用foreach遍历fields数组,结合Compose和If块实现,但条件判断结果始终不符合预期。
问题代码展示
// this works correctly: "Compose": { "inputs": { "@{item()['description']}": "@{item()['value']}" }, "runAfter": {}, "type": "Compose" }, "condition": { "actions": { // this works correctly "set_variable": { "inputs": { "name": "Result-fields", "value": "@outputs('Union_Compose')" }, "runAfter": { "Union_Compose": [ "Succeeded" ] }, "type": "SetVariable" }, // this works correctly "Union_Compose": { "inputs": { "result": "@{union(variables('Result-fields'), outputs('Compose'))}" }, "runAfter": {}, "type": "Compose" } }, // I tried different conditions: // body('Compose') contains "first name" or "last name": result: everytime false // body('Compose')['first name'] or body('Compose')['last name'] not equals null result: everytime true // body('Compose')['first name'] or body('Compose')['last name'] equals "*" (as wild card) but the result is everytime false! "expression": { "or": [ { "contains": [ "@{body('Compose')}", "first name" ] }, { "contains": [ "@{body('Compose')}", "last name" ] } ] }, "runAfter": { "Compose": [ "Succeeded" ] }, "type": "If" }
条件判断失效原因分析
contains(body('Compose'), "first name")始终为falsebody('Compose')返回的是JSON对象(如{"name": "Mickey"}),但contains函数仅支持检查字符串子串或数组元素,直接传入对象无法识别键名,导致判断失效。body('Compose')['first name'] or body('Compose')['last name'] not equals null始终为true
遍历非目标字段时,访问不存在的键会返回null,但表达式未正确使用Logic Apps的逻辑函数,直接拼接的逻辑或被解析为非空值,导致判断始终为true。通配符
*判断失效
Logic Apps的equals函数不支持通配符匹配,equals(body('Compose')['first name'], "*")会严格匹配字符串*,而非作为通配符使用,因此结果始终为false。
解决方案
方案1:修正条件表达式(基于遍历项直接判断)
无需依赖Compose输出,直接检查当前遍历项的description字段:
"expression": { "or": [ { "equals": [ "@{item()['description']}", "first name" ] }, { "equals": [ "@{item()['description']}", "last name" ] } ] }
或用contains简化逻辑:
"expression": { "contains": [ ["first name", "last name"], "@{item()['description']}" ] }
方案2:简化流程(无需foreach和变量)
用reduce和union函数一次性构建目标JSON,避免遍历和条件判断的复杂度:
@{ union( createObject('email', body('原始JSON')['email']), reduce( body('原始JSON')['fields'], createObject(), if( contains(['first name','last name'], item()['description']), union(item(), createObject(item()['description'], item()['value'])), item() ) ) ) }
执行后直接生成目标JSON:
{ "email": "donald.duck@waltdisney.com", "first name": "Donald", "last name": "Duck" }
内容的提问来源于stack exchange,提问作者Filippo1980
相关产品推荐
相关产品推荐

