You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM策略设置Body与返回响应遇500错误及数组校验问题

Azure APIM策略500错误排查及工单状态检查方案

一、set-body引发500错误的修复

你当前的set-body写法存在JSON格式隐患:当insured-id是字符串类型时,手动拼接的JSON会缺失引号,比如insured-id为"INS123"时,生成的请求体是{"insuredId": INS123},这不符合JSON语法,导致外部API解析失败,最终APIM返回500错误。

两种修复方式:

  • 方式1:补全字符串引号
    修改set-body为:

    <set-body>{"insuredId": "@(${(string)context.Variables["insured-id"]})"}</set-body>
    

    给插值结果套上双引号,确保字符串类型的insuredId符合JSON格式。

  • 方式2:用JObject构建请求体(更推荐)
    借助Newtonsoft.Json的JObject自动处理格式,彻底避免手动拼接的错误:

    <set-body>@(JObject.FromObject(new { insuredId = context.Variables["insured-id"] }).ToString())</set-body>
    

    这种方式会自动识别insured-id的数据类型,生成合法的JSON结构。

二、检查工单数组中是否存在entityStatus=1的记录

原代码中直接通过["workRequests"]["entityStatus"]访问是错误的,因为workRequests是数组类型,不能直接用键值对的方式获取字段。需要遍历数组中的每个工单对象,判断是否存在符合条件的记录。

修改后的choose条件代码如下:

<choose>
    <when condition="@(
        ((IResponse)context.Variables["id"]).Body.As<JObject>(preserveContent: true)["workRequests"]?
        .As<JArray>()
        .Any(workReq => (int?)workReq["entityStatus"] == 1)
    )">
        <return-response response-variable-name="id">
            <set-status code="400" reason="VOID" />
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body>{"statusCode": 400,
                        "message": "The insured cannot be voided as it is currently attached with one or more active workrequest"}</set-body>
        </return-response>
    </when>
    <otherwise />
</choose>

关键说明:

  1. 用As<JArray>()将workRequests转换为数组类型,方便遍历
  2. 使用Any()方法判断数组中是否存在任意一个工单的entityStatus等于1
  3. 添加(int?)空值转换,避免部分工单缺失entityStatus字段时引发空引用异常

三、完整修正后的策略代码

<set-variable name="newRequest" value="@(context.Request.Body?.As<JObject>(preserveContent: true))" />
<set-variable name="insured-id" value="@(context.Request.MatchedParameters["id"].Last())" />
<send-request mode="new" timeout="20" response-variable-name="id" ignore-error="false">
    <set-url>@($"https://api.dev.com/external/workRequest/get")</set-url>
    <set-method>POST</set-method>
    <set-header name="Content-Type" exists-action="override">
        <value>application/json</value>
    </set-header>
    <set-header name="Authorization" exists-action="override">
        <value>@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param"))</value>
    </set-header>
    <!-- 用JObject构建请求体,避免格式错误 -->
    <set-body>@(JObject.FromObject(new { insuredId = context.Variables["insured-id"] }).ToString())</set-body>
</send-request>
<choose>
    <when condition="@(
        ((IResponse)context.Variables["id"]).Body.As<JObject>(preserveContent: true)["workRequests"]?
        .As<JArray>()
        .Any(workReq => (int?)workReq["entityStatus"] == 1)
    )">
        <return-response response-variable-name="id">
            <set-status code="400" reason="VOID" />
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body>{"statusCode": 400,
                        "message": "The insured cannot be voided as it is currently attached with one or more active workrequest"}</set-body>
        </return-response>
    </when>
    <otherwise />
</choose>

内容的提问来源于stack exchange,提问作者Shree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:35:28