I have recently found a mixture of AX 2012 / D365 code online when
it comes to calling external REST web API’s directly from AX/D365FO. It seems
as though in today’s world the majority of people only care about calling and
receiving JSON or XML or some type of text-based object which the majority of
time holds true. But what happens when that API should return some type of file
or object rather than raw text where we want to save or serve up the file?
This is where it gets tricky because the System.IO.StreamReader like shown within the majority of examples online doesn’t provide the structure that we need in order to access binary objects to be able to send a file to the user or display something on the screen. It is however great when it comes to reading text based responses.
The key to understanding the framework is once we are able to put the main
System.IO.Stream into a System.IO.MemoryStream then we are easily able to
convert the binary objects to various output's.
The best way to describe is that System.IO.Stream operates much
like a FormRun object. It is the top most level and once we get access to that
then we can access any child objects like StreamReader or MemoryStream which
can then be handled differently based on the scenario.
Below is an example how to call a generic RESTful API via a post (the request structure may change based on your specific API being called)
System.Exception clrError;
InteropPermission interopPermission;
System.Net.HttpWebRequest request;
System.IO.Stream stream;
System.Byte[] zpl = System.Text.Encoding::UTF8.GetBytes("post body");
request = System.Net.WebRequest::Create("API URL") as System.Net.HttpWebRequest;
request.Method = 'POST';
request.Accept = "image/png"; //document type to generate
request.ContentType = 'application/x-www-form-urlencoded';
try
{
interopPermission = new InteropPermission(InteropKind::ComInterop);
interopPermission.assert();
// send out the payload
using (System.IO.Stream dataStream = request.GetRequestStream())
{
dataStream.Write(zpl, 0, zpl.Length);
}
using (System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse)
{
stream = response.GetResponseStream();
System.IO.MemoryStream filestream = new System.IO.MemoryStream();
//we need to convert the main stream to a memory stream in order to access the binary objects
stream.CopyTo(filestream);
//send the memory stream directly to the user which now contains a file object
File::SendFileToUser(filestream, "test.png");
}
}
catch (Exception::CLRError)
{
//catch any clr error
clrError = CLRInterop::getLastException();
if (clrError != null)
{
clrError = clrError.InnerException;
throw error(clrError.ToString());
}
}
finally
{
CodeAccessPermission::revertAssert();
}
No comments:
Post a Comment