I wanted to download a PDF of various transaction types (sales orders, invoices, etc.) from a RESTlet called from a C# application. Once I learned the “secret handshake”, it was easy.
Here is the well-kept secret:
First, the RESTlet… It returns a Base-64 encoded string. There is no need to JSON.stringify() it. Simply send it back as-is.
I’m calling my RESTlet using a System.Net.WebRequest object in the .NET Framework. Here’s what that looks like. The request uses a JSONized object to pass parameters, but the response comes back as a Base-64 encoded string.
In the code below, I’m showing how to format the PDF so the browser will know it is an attachment. I’ve hard-coded the internal ID of the sales order and am passing it as a parameter. I’m also passing the document type of “PDF.” The trick was decoding the Base-64 file to a byte array and writing it using the Response.BinaryWrite() function.
Here is what this looks like when it executes. In Internet Explorer, I get prompted to download the PDF.
And then I open a nicely formatted PDF.
The reason I requested a PDF instead of raw HTML is because it didn’t format correctly without the required style sheets. Delivering it as a fully formatted attachment guaranteed it looked right.
Here is some code you can paste into your project.
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add(“request”, “printTransaction”);
parameters.Add(“tranid”, “xxxxxx”);
parameters.Add(“doctype”, “pdf”);
OAuthCommon oAuthCommon = new OAuthCommon();
HttpWebResponse response = oAuthCommon.RESTletPOSTrequest(parameters);
Stream responseStream = response.GetResponseStream();
using (var reader = new StreamReader(responseStream))
{
// get the response as text
string responseString = reader.ReadToEnd();
var result = JsonConvert.DeserializeObject(responseString);
Response.Clear();
Response.ContentType = “Application/pdf”;
Response.AppendHeader(“Content-Disposition”, “attachment; filename=Test_PDF_xxxxxx.pdf”);
Response.BinaryWrite(Convert.FromBase64String(result.ToString()));
Response.End();
}
public HttpWebResponse RESTletPOSTrequest(Dictionary<string, object> Parameters)
{
const string requestMethod = “POST”;
string header = CreateOAuthHeader(requestMethod, “”);
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(baseURL);
request.ContentType = “application/json”;
request.Method = requestMethod;
request.Headers.Add(header);
string jsonData = JsonConvert.SerializeObject(Parameters);
using (var w = new StreamWriter(request.GetRequestStream()))
{
w.Write(jsonData);
w.Flush();
w.Close();
}
return (HttpWebResponse) request.GetResponse();
}
Thanks for making me aware of this post. Could you post the CreateOAuthHeader method?
LikeLike
Kevin, I believe you are asking 2 different questions. One is how to call a restlet, and the other is TBA authentication. Please See https://followingnetsuite.com/2018/09/21/suitetalk-tba-example-in-c/ for help with TBA. I made a correction to that post later when HMACSHA1 was deprecated and HMACSHA256 replaced it. You’ll find the details here https://followingnetsuite.com/2021/06/17/suitetalk-2021-2-deprecating-hmac-sha1/
LikeLike
Again thanks for posting this article. I was able to use snippets from your post and another blog to get it working. For anybody reading this, the other blog uses SHA1 and I had to update to SHA256. https://antonypetras.com/blog/netsuite-using-token-authentication-with-c-sharp/
LikeLike