'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?
Solution 1:[1]
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>
Solution 2:[2]
If I use below , I get below error. Error in element 'set-body' on line 30, column 15: Usage of member 'ToString' of type 'System.Object' is not supported within expressions
My outbound policy look like this.
<outbound>
<base />
<return-response>
<set-status code="200" reason="Success" />
<set-header name="Accept-Encoding" exists-action="override">
<value>deflate</value>
</set-header>
<set-header name="WWW-Authenticate" exists-action="override">
<value>PatientID Received="PatientKey0001"</value>
</set-header>
<set-body>@{
JToken body = context.Request.Body.As<JToken>();
if (body.Type == JTokenType.Array)
{
}
if (body.Type == JTokenType.Object)
{
}
return context.Request.Body.ToString();
}
</set-body>
</return-response>
</outbound>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Nasir Khan |
