azure 无法在APIM策略中设置正文和返回响应,收到500错误

idv4meu8  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(183)

我将此代码用于Azure APIM策略

<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>
    <set-body>{"insuredId": @($"{(string)context.Variables["insured-id"]}")}</set-body>
</send-request>
<choose>
    <when condition="@((int)((IResponse)context.Variables["id"]).Body.As<JObject>(preserveContent: true)["workRequests"]["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>

我从实现APIM策略的API操作的模板参数中获取一个insuredId,并在集合体中使用它,这将列出该insuredId的所有工作请求。
POST的有效负载类似于

{"insuredId": template-parameter}

当返回一个响应得到500错误。如何解决这个问题。条件是好的。我怀疑在设置体错误。
还有如何检查API的响应中是否有像"entityStatus": 1这样的特定字符串,因为这个https://api.dev.com/external/workRequest/get url会以数组形式给予一个工作请求记录的列表

5vf7fwbs

5vf7fwbs1#

https://api.dev.com/external/workRequest/get的请求失败:
"消息":"已向'https://api.dev.com/external/workRequest/get'发送POST请求,结果存储在'id'变量中。",
"状态代码":"方法不允许",
"状态原因":"方法不允许",
请求失败的响应存储在变量id中,但该响应的正文中不返回任何json文档。
因此,以下表达式失败,并返回错误500:
"(int)((IResponse)context.Variables[\"id\"]).Body.As<JObject>(preserveContent: true)[\"workRequests\"][\"entityStatus\"]== 1",
消息正文不是有效的JSON。分析值时遇到意外字符:〈.路径"",第0行,位置0。\r\n位于Newtonsoft. Json. JsonTextReader.分析值()\r\n位于Microsoft. WindowsAzure. ApiManagement.代理.运行时.配置.模型. SyncOnlyDepthTrackingJsonTextReader.读取()\r\n位于牛顿软件. JSON. Linq. JObject.加载(JsonReader读取器,JsonLoadSettings设置)\r\n位于网关.管道. IO. JObjectFormatter.格式(JsonTextReader)\r\n位于网关.管道. IO. JsonConverter.转换[T](流媒体流、编码编码、ILog日志、对象转换设置)\r\n位于Microsoft. WindowsAzure. ApiManagement.代理.网关.消息正文. As [T](布尔值保留内容)
请检查https://api.dev.com/external/workRequest/get支持的http方法。
也许您的代码必须更改为GET

<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>GET</set-method>

请求跟踪:

    • 更新评论中的问题:**

谢谢,我解决了这个问题。我使用的when条件语法错误,因为我得到的响应是数组列表{" workRequests ":[{" id ":154,"工作请求编号":"W000154"、"被保险人":{"编号":268," URI ":空,"实体状态":1、"工作请求状态":0,"实体状态":1}、......。
最好创建一个新的Stackoverflow问题,而不是在评论中这样做。也许这就是你所要求的:
请求正文:

{
  "workRequests": [
    {
      "id": 154,
      "workRequestNumber": "W000154",
      "insured": {
        "id": 268,
        "uri": null,
        "entityStatus": 1,
        "workRequestStatus": 0
      }
    },
    {
      "id": 154,
      "workRequestNumber": "W000154",
      "insured": {
        "id": 268,
        "uri": null,
        "entityStatus": 0,
        "workRequestStatus": 0
      }
    }
  ]
}

回复:

为变量分配entityStatus等于1的任何true值。
choose策略返回400,其中entityStatus等于true
政策:

<inbound>
    <base />
    <set-variable name="isEntityStatusEqualsOne" value="@{
        var body = (JObject)context.Request.Body.As<JObject>(true);
        JArray workrequests = body["workRequests"] as JArray; 
        for(int i = 0; i < workrequests.Count; i++)
        {
            JObject workrequest = workrequests[i] as JObject;
            var entityStatus = ((JValue)workrequest["insured"]["entityStatus"]).Value<int>();
            if(entityStatus == 1)
            {
                return true;
            }
        }

        return false;
    }" />
    <choose>
        <when condition="@(context.Variables.GetValueOrDefault<bool>("isEntityStatusEqualsOne") == true)">
            <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>
            <return-response response-variable-name="id">
                <set-status code="200" reason="OK" />
            </return-response>
        </otherwise>
    </choose>
</inbound>

相关问题