Hello professionals,
I'm trying to add BLOB image to JSon request send to API.
First of all I'm converting that photo to BigInteger and after that it's converted into base64string.
APIUploadProductImage(ProductID : Text)
CLEAR(ImageBigText);
recItem.SETRANGE(recItem."No.", '10000');
IF recItem.FINDFIRST THEN BEGIN
recItem.CALCFIELDS(Picture);
IF NOT recItem.Picture.HASVALUE THEN
EXIT;
recItem.Picture.CREATEINSTREAM(Istream);
MemoryStream := MemoryStream.MemoryStream();
COPYSTREAM(MemoryStream,Istream);
Bytes := MemoryStream.ToArray();
ImageBigText.ADDTEXT(Convert.ToBase64String(Bytes));
END;
JsonMgt.StartJSon;
JsonMgt.AddToJSon('image',ImageBigText);
JsonMgt.EndJSon;
String := String.Copy(JsonMgt.GetJSon);
WebServiceURL := '
https://XXXXXXXXXXXXXX/api/2.0/products/'+ProductID+'/actions/image_upload/';
HttpWebRequest := HttpWebRequest.Create(WebServiceURL);
HttpWebRequest.Method := 'POST';
HttpWebRequest.KeepAlive := TRUE;
HttpWebRequest.Timeout := 30000;
HttpWebRequest.Accept('application/json');
HttpWebRequest.ContentType('multipart/form-data');
HttpWebRequest.Headers.Add('Authorization: Bearer ' + 'XXXXXXXXXXXX');
StreamWriter := StreamWriter.StreamWriter(HttpWebRequest.GetRequestStream,Encoding.GetEncoding('iso8859-1'));
StreamWriter.Write(String);
StreamWriter.Close;
NAVWebRequest := NAVWebRequest.NAVWebRequest;
NAVWebRequest.doRequest(HttpWebRequest,HttpWebException,HttpWebResponse);
##########!!!!!!!!!!################!!!!!!!!!!!
and here it breaks at this line.
Error shows:
System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
at NAVWebRequest.NAVWebRequest.doRequest(HttpWebRequest& WebRequest, WebException& WebException, WebResponse
I'm new with JSon. My brain already stopped working. And I can create/get request/response but in case of adding BLOB to request I have to give up... I think something is wrong with converting blob>biginteger>here?
JsonMgt.Start, add & endJson are functions which are building json schema around data which I'm providing. It works for normal data so it's not problem with it.
Any hints lads? Any idea, tip, all those will be helpful!
Ahh and I'm working on NAV2016.
Thanks in advance!
Tim
Comments
A piece of working code from my solution, in this case I also post as json to a service.: (NCImageContent = Text)
NCImage.CALCFIELDS(Data);
IF NCImage.Data.HASVALUE THEN BEGIN
NCImage.Data.CREATEINSTREAM(InStreamBlob);
MemoryStream := MemoryStream.MemoryStream;
COPYSTREAM(MemoryStream, InStreamBlob);
Bytes := MemoryStream.ToArray;
NCImageContent := Convert.ToBase64String(Bytes);
END;
You are getting a 500 response from the server, can't you debug it on that side?
Are you hosting the http service on an Azure machine or app service? The Azure gateway in front of VM's and services does not allow posting 'large' (>50KB) objects. We had the same issue.
Surely you know that the BigText variable in a web service behaves like a normal string - but without the 1024 character limit. Therefore I prefer to use BigText 'just in case'
I have looked at example from:
http://kauffmann.nl/index.php/2012/04/04/binary-data-with-nav-web-service/
I can't debug server's side - I'm trying to use VendAPI.
The image data should be just bytes of the image file, as bytes. (that's exact sentence from their support)
So it doesn't matter if it's text or bigtext because both are send as string at the end and both are not working. Just checked normal text and it's the same.
Other ideas?
Attached image shows attribute which I need to send (just one) and req header needed - both are in my code.
But anyway, the only thing I would check is copying the base64 string and convert it back to the image. Is your file a valid jpeg afterwards? If so, validate the complete json string in a json validator.
If you are sure your json string is valid, call someone who can actually check the server. Maybe there are some useful logs on there. A 500 error is a b*tch. Basically, the code handling your request on the server is not handling the exception but is instead just throwing a general error which gives you no pointers.
I have done quick function which takes image from one item, converts it to 64string text and then from it it converts it back to what it was and modifies second item image:
IF recItem.FINDFIRST THEN BEGIN
recItem.CALCFIELDS(Picture);
IF NOT recItem.Picture.HASVALUE THEN
EXIT;
recItem.Picture.CREATEINSTREAM(Istream);
MemoryStream := MemoryStream.MemoryStream;
COPYSTREAM(MemoryStream,Istream);
Bytes := MemoryStream.ToArray;
ImageText := Convert.ToBase64String(Bytes);
END;
recItem.SETRANGE("No.",'10001');
IF recItem.FINDSET(TRUE,TRUE) THEN BEGIN
recItem.CALCFIELDS(Picture);
IF recItem.Picture.HASVALUE THEN
EXIT;
Bytes := Convert.FromBase64String(ImageText);
MemoryStream := MemoryStream.MemoryStream(Bytes);
recItem.Picture.CREATEOUTSTREAM(Ostream);
MemoryStream.WriteTo(Ostream);
recItem.MODIFY;
END;
But it works fine what means blob is converted correctly...
I have compared both with KDiff and they were binary the same.
I'm sure about my json schema because I can easily use other endpoints which are more complicated because there are arrays in arrays or other have more attributes where this has only one...
Their API support is useless. They can't check logs, you can't contact them in other way than mail and they respond minimum day after because their office is in New Zealand...
Yes, 500 error is a b*tch.