简体   繁体   中英

Accessing context.Request.Body in APIM policy removes request body

I'm trying to extract a specific attribute from the JSON body and add that as a header value. This should be straight forward as such:

    <set-header name="x-bp-currency" exists-action="override" >
        <value>@((string)context.Request.Body.As<JObject>()["currency"])</value>
    </set-header>

But, I see that when I do this, the request-body gets removed before it is forwarded to the backend URL. I've managed to narrow it down that the context.Request.Body is causing the issue. If we add a hardcoded value, then the request-body is still sent to the backend.

Example:

This keeps the original request-body and forwards to the backend:

   <inbound>
        <base />
        <set-header name="x-bp-currency" exists-action="override">
            <value>test</value>
        </set-header>
        <set-backend-service base-url="https://webhook.site/xxxxx" />
    </inbound>

This removes the request-body (content-length: 0).

   <inbound>
        <base />
        <set-header name="x-bp-currency" exists-action="override" >
            <value>@((string)context.Request.Body.As<JObject>()["currency"])</value>
        </set-header>
        <set-backend-service base-url="https://webhook.site/xxxxx" />
    </inbound>

Even just adding the whole request-body to a variable causes the request-body to be removed (either as JObject or string):

    <inbound>
        <base />
        <set-variable name="test" value="@(context.Request.Body.As<JObject>())" />
        <set-backend-service base-url="https://webhook.site/xxxxx" />
    </inbound>

or

    <inbound>
        <base />
        <set-variable name="test" value="@(context.Request.Body.As<string>())" />
        <set-backend-service base-url="https://webhook.site/xxxx" />
    </inbound>

Not that good documentation around this, but if you access context.Request.Body, it cannot be accessed again further in the policy, and it seems that this is true for the request moving forward to the backend.

There was no good documentation on this , but I find it strange that my google searches did not see others with similar issues.

The way to specify preserveContent: true in the set-header is as such:

<inbound>
    <base />
    <set-header name="x-bp-currency" exists-action="override">
        <value>@((string)context.Request.Body.As<JObject>(preserveContent: true)["currency"])</value>
    </set-header>
    <set-backend-service base-url="https://webhook.site/xxxxx" />
</inbound>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM