How to config policy to call backend with body x-www-form-urlencoded ?

Amy Zhang 25 Reputation points
2023-03-07T07:20:09.08+00:00

Hi, we have a backend API whose body is like these
x-www-form-urlencodedFrom_API_Provider

We hope API consumer can call api through APIM like this

For_API_Consumer

Not sure how to config the policy to meet this requirement.

We've tried to config like this but with not luck.

<inbound>
        <set-body>@{ 
            var body = context.Request.Body.AsFormUrlEncodedContent();
            return body.ToFormUrlEncodedContent(); 
        }</set-body>
        <base />
        <set-backend-service base-url="https://xxx.com/portal.php" />
    </inbound>

The error is like this

"messages": [
        {
            "message": "Expression evaluation failed.",
            "expression": " \n            var body = context.Request.Body.AsFormUrlEncodedContent();\n            return body.ToFormUrlEncodedContent(); \n        ",
            "details": "The form-url-encoded-content is not correctly formatted.Last read content {\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}\r\n   at Gateway.Pipeline.IO.FormUrlEncodedConverter.ThrowException(String errorMessage)\r\n   at Gateway.Pipeline.IO.FormUrlEncodedConverter.Convert[T](Stream stream, Encoding encoding, ILog log, Object conversionSettings)\r\n   at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody.Convert[T](Boolean preserveContent, JsonSerializerSettings settings)"

Need your guidance. Thank you

Azure API Management
Azure API Management
An Azure service that provides a hybrid, multi-cloud management platform for APIs.
2,462 questions
{count} votes

1 answer

Sort by: Most helpful
  1. MuthuKumaranMurugaachari-MSFT 22,441 Reputation points Moderator
    2023-03-08T21:48:29.5333333+00:00

    Amy Zhang Thank you for posting this question in Microsoft Q&A. Based on my understanding, you have a backend API which expects content-type as x-www-form-urlencoded but you need to pass the request body as JSON to APIM. Is that correct?

    The above code snippet based on doc: Access and return body as URL-encoded form data is expecting the request body as x-www-form-urlencoded but the actual request body was JSON and hence it failed. Looking at the Postman request, it formed key/pair value, and you can achieve the same by writing a custom policy with set-body.

    User's image

    Sample code snippet:

    <set-header name="Content-Type" exists-action="override">
                <value>application/x-www-form-urlencoded</value>
            </set-header>
            <set-body>@{
                JObject varBody = context.Request.Body.As<JObject>(preserveContent:true);
                return $"k1={varBody["k1"]}&k2={varBody["k2"]}&k3={varBody["k3"]}";
            }</set-body>
    

    The above code snippet is just for reference, and you can write generic policy expressions based on your need. Refer API Management policy expressions and for more samples, check out Azure API Management Policy Snippets.

    I hope this helps with your question and let me know if you have any other. Would be happy to answer any.


    If you found the answer to your question helpful, please take a moment to mark it as "Yes" for others to benefit from your experience. Or simply add a comment tagging me and would be happy to answer your questions.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.