Hi!
Check the following example to learn how to handle blobs with XData and TMS Web Core:
I will, thank you!
procedure TfrmNew.UpdatePicture;
var
xhr: TJSXmlHttpRequest;
begin
xhr := TJSXMLHttpRequest.new;
// xhr.open('PUT', connServer.URL+'/'+string(TJSObject(wdsPobuda.CurrentData)['Slika@xdata.proxy']));
xhr.open('PUT', connServer.URL+'/'+string('pobuda(1)/Slika')); //<-- like this because TJSObject(wdsPobuda.CurrentData) is always empty!
xhr.send(imgSlika.Base64Image);
end;
procedure TfrmDetails.ShowPicture;
var
xhr: TJSXmlHttpRequest;
procedure _Load;
var stream: TBytesStream;
begin
stream := TBytesStream.Create(DecodeBase64(xhr.responseText));
imgSlika.Picture.LoadFromStream(stream);
end;
begin
xhr := TJSXMLHttpRequest.new;
// xhr.open('GET', connServer.URL+'/'+string(TJSObject(wdsPobuda.CurrentData)['Slika@xdata.proxy']));
xhr.open('GET', connServer.URL+'/pobuda(1)/Slika'); //<-- like this because TJSObject(wdsPobuda.CurrentData) is always empty!
xhr.addEventListener('load', @_Load);
xhr.send;
end;
wdsPobuda.QueryString := '$filter=Id lt ''1''';
wdsPobuda.Load;
wdsPobuda.Append;
// wdsPobuda.FieldByName('Id').AsInteger := autogenerated on insert
wdsPobuda.FieldByName('Description').AsInteger := 'test';
wdsPobuda.Post;
wdsPobuda.ApplyUpdates;
ShowMEssage(wdsPobuda.FieldByName('Id').AsString); <-- this shows the latest Id after the insert.
What type is imgSlika?
XData: latest version (updated few days ago).
To display the picture I use the TWebDBImageControl linked to a field "Slika" of the TXDataWebDataset
Invalid integer value: "$ZC" | fMessage::Invalid integer value: "$ZC" fHelpContext::0
at http://localhost:8000/Okolje24/Okolje24.js [3138:12]
procedure TfrmNew.UpdatePicture;
var
xhr: TJSXmlHttpRequest;
begin
xhr := TJSXMLHttpRequest.new;
xhr.open('PUT', connServer.URL+'/'+string('pobuda('+wdsPobuda.FieldByName('Id').AsString+')/Slika'));
xhr.send(imgSlika.Base64Image);
end;
You can load the image directly into the TWebImageControl using this code:
WebImageControl1.Url := XDataWebConnection1.URL + '/' +
string(TJSObject(XDataWebDataset1.CurrentData)['Photo@xdata.proxy']);
Done, but the picture is still missing (but no errors in browser console). For double check - here's how I save the picture:
procedure TfrmNew.UpdatePicture;
var
xhr: TJSXmlHttpRequest;
begin
xhr := TJSXMLHttpRequest.new;
xhr.open('PUT', connServer.URL+'/'+string('pobuda('+wdsPobuda.FieldByName('Id').AsString+')/Slika'));
xhr.send(imgSlika.Base64Image);
end;
procedure TfrmNew.wdsPobudaAfterApplyUpdates(Sender: TDataSet; Info: TResolveResults);
begin
UpdatePicture;
ModalResult := mrOk;
end;
procedure TfrmDetails.wdsPobudaAfterOpen(DataSet: TDataSet);
begin
imgSlika2.Url := connServer.URL + '/' +string(TJSObject(wdsPobuda.CurrentData)['Slika@xdata.proxy']);
end;
You should send the raw binary image to the server, not the base64 value. This is what you should use:
function Base64ToArrayBuffer(str: string): TJSArrayBuffer;
var
BufView: TJSUInt8Array;
BinaryString: string;
I: Integer;
begin
BinaryString := window.atob(str);
Result := TJSArrayBuffer.new(Length(BinaryString));
BufView := TJSUInt8Array.new(Result);
for I := 0 to Length(BinaryString) - 1 do
BufView := TJSString(BinaryString).charCodeAt(I);
end;
xhr.send(Base64ToArrayBuffer(WebImageControl1.Base64Image));
It's working!
Mistake - correct is:
I found a bug in the forum - you cannot add text with square brackets :)
ops.. :)
I think the code has a strange thing
function Base64ToArrayBuffer(str: string): TJSArrayBuffer;
var
BufView: TJSUInt8Array;
BinaryString: string;
I: Integer;
begin
BinaryString := window.atob(str);
Result := TJSArrayBuffer.new(Length(BinaryString));
BufView := TJSUInt8Array.new(Result);
for I := 0 to Length(BinaryString) - 1 do
BufView := TJSString(BinaryString).charCodeAt(I);
end;
No, it's needed to convert the characters to actual byte value (a string to an array of bytes).
Hi
If you are using sqlserver database in your application
you can use sqlserver filetable and then share vitural directory of sqlserver filetable on IIS
then load and save picture easily on it.
An old topic, a supplementary question.
I'm working on the "Xdata-blob-webcore" example.
My XData Server needs Authorization. (Bearer token).
When I load the image, the central "OnConnectionRequest" probably doesn't go through because I get an "Unauthorized" error message.
In the debugger, I see the right URL.
A test in "Postman" with token works perfectly.
How can I send the token? Or what do I have to change in the example? Is there another "connection" here?
I believe you are referring to this code which sets an image:
WebImageControl1.Url := XDataWebConnection1.URL + '/' +
string(TJSObject(XDataWebDataset1.CurrentData)['Photo@xdata.proxy']);
In this case, the event will not be fired indeed because you are just setting an URL for the browser to load the image. You will have to load the image bytes directly from JavaScript and then set the image data in the URL:
procedure TForm1.WebButton6Click(Sender: TObject);
var
xhr: TJSXmlHttpRequest;
procedure _Load;
begin
WebImageControl1.Url := TJSURL.createObjectURL(xhr.response);
end;
begin
xhr := TJSXMLHttpRequest.new;
xhr.open('GET',
XDataWebConnection1.URL + '/' +
string(TJSObject(XDataWebDataset1.CurrentData)['Photo@xdata.proxy'])
);
xhr.responseType := 'blob';
xhr.addEventListener('load', @_Load);
xhr.send;
end;
With the code above, you can set any headers you need, including the authorization one.