Problem: Upload/Download files via Webservice

marvinqmarvinq Member Posts: 69
edited 2013-02-05 in NAV Three Tier
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:
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! :|
1.PNG 15.7K
2.PNG 25.2K

Comments

  • deV.chdeV.ch Member Posts: 543
    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.
  • marvinqmarvinq Member Posts: 69
    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?

    Thanks
  • deV.chdeV.ch Member Posts: 543
    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 by
    var fstream = File.OpenRead(@"C:\Temp\input.txt");
    upload.UploadFile(fstream);
    
  • marvinqmarvinq Member Posts: 69
    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.
  • deV.chdeV.ch Member Posts: 543
    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;
    
  • marvinqmarvinq Member Posts: 69
    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.
  • deV.chdeV.ch Member Posts: 543
    Yeah that true for client was for testing because i tested it on rtc rather then on webservice.
    Good hint! :thumbsup:
  • casanovacasanova Member Posts: 194
    can we change file(xml,txt,csv file) from handheld to be inserted to nav via webservice?
Sign In or Register to comment.