Adding BLOB image to JSon request

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

  • timosman369timosman369 Member Posts: 16
    anyone?
  • EvREvR Member Posts: 178
    edited 2016-09-19
    Why are you adding to a bigtext in the first place?
    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.
  • timosman369timosman369 Member Posts: 16
    Thanks for your reply.

    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' :wink:

    I have looked at example from:
    http://kauffmann.nl/index.php/2012/04/04/binary-data-with-nav-web-service/

    EvR wrote: »
    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.

    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.
  • EvREvR Member Posts: 178
    Thanks for your reply.
    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' :wink:
    Since NAV7 (2013), the 1024 length text limitation is gone.

    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.
  • timosman369timosman369 Member Posts: 16
    edited 2016-09-19
    EvR wrote: »
    Since NAV7 (2013), the 1024 length text limitation is gone.
    Thanks , good to know... :neutral:

    EvR wrote: »
    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.
    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.

    EvR wrote: »
    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'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. :/
  • timosman369timosman369 Member Posts: 16
    up
  • KalelKalel Member Posts: 4
    Timosman? did you get to fix it? I have the same problem I would like to know what solution you found?
Sign In or Register to comment.