简体   繁体   中英

Condition to check context.Request.Body is JArray or JObject in azure api management policy

I am using Azure API Management policy expression to send the Supplier value into each post, put and delete request to backend API. I wrote a code which was working fine when the request type of JObject. but I have some case where the request can be type of JArray, in that case it throw 500 error. The below snippet is working fine for JObject.

    <set-variable name="Supplier" value="DummySupplier" />
    <choose>
        <when condition="@(new [] {"post", "put", "delete"}.Contains(context.Request.Method, StringComparer.OrdinalIgnoreCase))">
            <set-body>@{ 
                         JObject body = context.Request.Body.As<JObject>(); 
                         body.Add(new JProperty("Supplier", ((string)context.Variables["Supplier"])));
                         return body.ToString(); 
                      }
            </set-body>
        </when>
    </choose>

I need a condition where I can check the request body type and parse accordingly. Otherwise in case of if request body is IEnumerable/JArray type, then above code gives me error.

Getting below error when I have an IEnumerable in request body

The message body is not a valid JSON. Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.

at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader, JsonLoadSettings settings)
at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody.AsJObject(Stream stream, Encoding encoding, JsonSerializerSettings settings)
at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody.As[T](Boolean preserveContent)

Could you please help me out with this?

Not the cleanest solution, but works considering your requirement here. Note that I am now parsing as JToken below which is the base of both JObject and JArray. Then doing things after checking the type.

<set-variable name="Supplier" value="DummySupplier" />
    <choose>
        <when condition="@(new [] {"post", "put", "delete"}.Contains(context.Request.Method, StringComparer.OrdinalIgnoreCase))">
            <set-body>@{ 
                         JToken body = context.Request.Body.As<JToken>();
                         if (body.Type == JTokenType.Array)
                         {
                             JObject newBody = new JObject();
                             newBody["OriginalArray"] = body;
                             newBody["Supplier"] = (string)context.Variables["Supplier"];                             
                             return newBody.ToString();
                         }

                         if (body.Type == JTokenType.Object)
                         {
                             body["Supplier"] = (string)context.Variables["Supplier"];
                             return body.ToString();
                         }
                         
                         return context.Request.Body.ToString();
                       }
            </set-body>
        </when>
    </choose>

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