Problem: Upload/Download files via Webservice

marvinq
Member Posts: 69
Hi,
I have problems with upload-file and download-file sending from Client-Side to Server-Side.
I have created the following codeunit function in NAV2009sp1:
I have then made a small piece of C# code in a windows form which calls this function:
..but it replies that "Callbacks are not allowed".
For testing I created an action in RTC on client side and tried to run this function. At first I get this message:
And no matter what I answer this comes up:
And then (followed by RTC crash):
So first of all there is a callback, how can I make sure this does not show up when calling from Webservice. The company is not using RTC, so setting "Always allow" on each client is not really an option.
Secondly, why does it crash? I thought the problem was that CREATE was missing, but it did not help. Any ideas on how to get this to work? The example here is an upload-function, same problem occurs then trying to download.
Really looking forward to get some help. Thanks!
Extra info:
I just changed the code in NAV:
from >> CREATE(FileObject, TRUE, TRUE);
to >> CREATE(FileObject, FALSE, FALSE);
Now the RTC client does not crash, but comes up with the message:
Looks like NAV is not recognizing that the call is made from a client. It looks for the file locally on the server. Am I doing something completely wrong?
A error like this is also displayed when running direcly from within NAV Classic Client. And the C# application is still demanding no callbacks.
Help!
I have problems with upload-file and download-file sending from Client-Side to Server-Side.
I have created the following codeunit function in NAV2009sp1:
ClientFilePath := 'C:\Temp\test.txt'; CREATE(FileObject, TRUE, TRUE); Ext := FileObject.GetExtensionName(ClientFilePath); ClientTempFilePath := CU419.ClientTempFileName('',Ext); ClientTempFile := FileObject.GetFileName(ClientTempFilePath); FileObject.CopyFile(ClientFilePath,ClientTempFilePath,TRUE); ServerFilePath := CU419.ServerTempFileName('',Ext); Status := UPLOAD('',CU419.Magicpath,'',ClientTempFile,ServerFilePath); EXIT(Status);
I have then made a small piece of C# code in a windows form which calls this function:
UploadDownload_Binding upload = new UploadDownload_Binding(); upload.UseDefaultCredentials = true; upload.Url = @"http://" + servername + "/DynamicsNAV/WS/" + companyname + "/Codeunit/UploadDownload"; upload.UploadFunction();
..but it replies that "Callbacks are not allowed".
For testing I created an action in RTC on client side and tried to run this function. At first I get this message:
And no matter what I answer this comes up:
And then (followed by RTC crash):
So first of all there is a callback, how can I make sure this does not show up when calling from Webservice. The company is not using RTC, so setting "Always allow" on each client is not really an option.
Secondly, why does it crash? I thought the problem was that CREATE was missing, but it did not help. Any ideas on how to get this to work? The example here is an upload-function, same problem occurs then trying to download.
Really looking forward to get some help. Thanks!
Extra info:
I just changed the code in NAV:
from >> CREATE(FileObject, TRUE, TRUE);
to >> CREATE(FileObject, FALSE, FALSE);
Now the RTC client does not crash, but comes up with the message:
"This message is for C/AL programmers: The call to member CopyFile failed: Exception from HRESULT: 0x800A0035 (CTL_E_FILENOTFOUND)."
Looks like NAV is not recognizing that the call is made from a client. It looks for the file locally on the server. Am I doing something completely wrong?
A error like this is also displayed when running direcly from within NAV Classic Client. And the C# application is still demanding no callbacks.
Help!

0
Comments
-
IF you use webservices your C/AL Code is always executed on the service tier, there is no client / server thing going on, the client is your .net application, which of course can not execute your c/al code
The whole code for uploading will never work, you need to read your file into a stream and pass that stream to the webservice. then you can work with this stream directly.
I'am not exatly sure which callback you are getting, but the confirmation message for the automation should not be the problem, because this will not be shown in a webservice session.0 -
Hi deV.ch,
Thank you for your reply.
Okay you have a point. So code will work when running inside RTC client? and not when running C# applications? (I thought RTC was C# in runtime).
..This might answer my question on download problems posted in this thread: http://www.mibuso.com/forum/viewtopic.php?f=32&t=56596, where download works via RTC, and not works in C#, both client-side. Is that your point?
Do you have any examples on how to upload a stream?
Thanks0 -
RTC is indeed based on .net and written in c#. It may be confusing for you if i say that your c# application is not the same.
The confusion here is that you can run C/AL (NAV) Code either on the server or the client, but that only applies to a scenario where you use RTC as the client. Because you need a client who understands C/AL and knows about C/AL to execute this code. But your c# application does not know about this. it simply a consumer of a webservice. The only thing it does and can is invoking methods on the NAV server and eventually get data back from there.
Therefore the whole C/AL part happens on the server side. To go further, when you have an automation that you create by using the "OnClient" parameter then this automation is still created on the server, because there is only a server and no client (in nav perspective).
I have no working example of what you try to achieve, but the C/AL Code would look something like this:UploadFile(VAR _FileStream : InStream) MyFile.CREATE('C:\Temp\test.txt'); MyFile.CREATEOUTSTREAM(OStream); COPYSTREAM(OStream,_FileStream); MyFile.CLOSE
and the c# code you pass the file byvar fstream = File.OpenRead(@"C:\Temp\input.txt"); upload.UploadFile(fstream);
0 -
Hi,
Okay, thank you for your answer.
It helped a lot for the understanding, and confirmed my thoughts. I will give it a try with streams.0 -
As it turned out (marvin told me) i forgot about the fact that you cannot use streams in parameters of webservice functions.
Therefore the solution is to use base64 Encoding/Decoding on NAV side and use as BigText variable as parameter in the webservice functions.
For completeness here is the involved code for both directions and NAV side and c# client side:
(Note that the OP uses NAV2009SP1 and therefore is unable to use .net interop. With .net Interop Base64 Conversion is much easier, in fact you can use the Convert Class like in the client example above)
Client Side:// Encode var fileAsBase64String = Convert.ToBase64String(File.ReadAllBytes("C:\Temp\test.txt")); // Decode File.WriteAllBytes(@"c:\temp\yourfile.txt", Convert.FromBase64String(fileAsBase64String));
NAV Side:// Variables used: XMLDom Automation 'Microsoft XML, v3.0'.DOMDocument XMLNode Automation 'Microsoft XML, v3.0'.IXMLDOMNode ADOStream Automation 'Microsoft ActiveX Data Objects 2.7 Library'.Stream BStringConverter Automation 'Navision Attain Hash 1.0'.BSTRConverter i Integer TempString Text 1024
// Encoding --------------------------------------------------------------------------------------------- FileToBase64(_Filename : Text[250];VAR _Base64String : BigText) IF NOT ISSERVICETIER THEN ERROR('Service Tier only'); CREATE(XMLDom, TRUE, TRUE); XMLNode := XMLDom.createElement('base64Node'); XMLNode.dataType := 'bin.base64'; CREATE(ADOStream, TRUE, TRUE); ADOStream.Type := 1; ADOStream.Open; ADOStream.LoadFromFile(_Filename); XMLNode.nodeTypedValue := ADOStream.Read; ADOStream.Close; _Base64String.ADDTEXT(XMLNode.text);
// Decoding --------------------------------------------------------------------------------------------- FileFromBase64(_Filename : Text[250];_Base64String : BigText) IF NOT ISSERVICETIER THEN ERROR('Service Tier only'); CREATE(XMLDom, TRUE, TRUE); XMLNode := XMLDom.createElement('base64Node'); XMLNode.dataType := 'bin.base64'; // Create valid BSTR for XMLNode.Text CREATE(BStringConverter, TRUE, TRUE); i := 1; WHILE i <= _Base64String.LENGTH DO BEGIN i += _Base64String.GETSUBTEXT(TempString, i, MAXSTRLEN(TempString)) ; BStringConverter.AppendNextStringPortion(TempString); END; XMLNode.text(BStringConverter.BSTR); CREATE(ADOStream, TRUE, TRUE); ADOStream.Type := 1; ADOStream.Open; ADOStream.Write := XMLNode.nodeTypedValue; ADOStream.SaveToFile(_Filename); ADOStream.Close;
0 -
Hi,
... and it works. However I get callbacks in C# on "CREATE(xxx,TRUE,TRUE)". If you use default "CREATE(xxx)" or "CREATE(xxx, FALSE,FALSE)" instead, then no callbacks occur.0 -
can we change file(xml,txt,csv file) from handheld to be inserted to nav via webservice?0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions