Lately, I had the requirement to access data from the incoming HTTP body, which was form-urlencoded (Content-Type: application/x-www-form-urlencoded). I assumed this was something simple to do, however it turned out more complex than expected.
HttpUtility?
My first reflex was to leverage the HttpUtility.ParseQueryString .NET method. Unfortunately, the System.Web namespace is not available in Azure API Management.
Custom .NET
After some more research, I did not find any solution on the web, so I implemented it myself, using custom .NET C# inside my policy expression. Let’s have a look!
Create a named value
- To be able to reuse the code, I’ve created a named value, called httputility-get-formDecodedHttpBody.
- This named value contains the following code-block, which returns the key value pairs as a dictionary, named formDecodedHttpBody:
string httpBody = context.Request.Body.As<String>(preserveContent: true); var formDecodedHttpBody = new System.Collections.Generic.Dictionary<String, String>(); foreach (var encodedKeyValuePair in httpBody.Split('&')) { string decodedKey = System.Net.WebUtility.UrlDecode(encodedKeyValuePair.Split('=')[0]); string decodedValue = System.Net.WebUtility.UrlDecode(encodedKeyValuePair.Split('=')[1]); formDecodedHttpBody.Add(decodedKey, decodedValue); }
Access the form-urlencoded HTTP body
- You can now access the customer_id value from the HTTP body like this. Remark that this uses the named value we’ve created.
<set-body>@{ {{httputility-get-formDecodedHttpBody}} return formDecodedHttpBody["customer_id"]; }</set-body>
- To avoid NullReferenceExceptions, you can leverage the TryGetValue method.
<set-body>@{ {{httputility-get-formDecodedHttpBody}} string customerId; formDecodedHttpBody.TryGetValue("customer_id", out customerId); return customerId; }</set-body>
Conclusion
In my opinion, this is too much effort for such a simple task. It would be great if there was a more out-of-the-box solution. Do you have a better way to achieve this? Please let me know!
Cheers!
Toon