Time is flying! My last post is already more then four months ago, so it’s high time to post a new one.
Last week I was struggling with the UPLOAD statement. First of all, I always need some twisted thinking here: the code is running on the Service Tier, but DOWNLOAD doesn’t mean that you download a file to the server. And UPLOAD doesn’t mean that your code on the server will send a file to the Role Tailored Client. The opposite is true: it seems that these two statements are executed by the client instead of the server. Or at least you should think that way…
Ok, so DOWNLOAD means that you want to send a file from the server to the client while UPLOAD sends a file the other way.
The case that I was trying to solve, was to send a known file from the RTC to the Service Tier. Our customer wanted to attach a file (or complete folder) to an email. The email setup was to use SMTP and not Outlook integration.
The problem in this case is that SMTP Mail Codeunit runs on the Service Tier, while the file or folder setup was done via the RTC. So the user picked a folder that was local to the client and not available to the server.
No problem… we can UPLOAD the file(s), without showing any dialog box…., I thought…
We all know Codeunit 419 3-Tier Automation Mgt., which can be used for handling files between RTC and Service Tier. So I looked into this Codeunit to find the function that accepts a local file path on the client, upload it to the server and returns the server path. And I noticed that such a function is not available. Hmmm….
So I wrote my own UploadFile function in Codeunit 419 that does a silent upload to the Service Tier, which I want to share with you.
|FileInfo||DotNet||‘mscorlib, Version=22.214.171.124, Culture=neutral, PublicKeyToken=b77a5c561934e089’.System.IO.FileInfo|
FileInfo should have property RunOnClient = Yes.
[codesyntax lang=”progress” title=”UploadFile”]
UploadFile(ClientFileName : Text) : Text FileInfo := FileInfo.FileInfo(ClientFileName); ClientTempFileName(FileInfo.Name,FileInfo.Extension); IF FileInfo.DirectoryName + '\' <> ClientTempPath THEN FileInfo.CopyTo(ClientTempPath + FileInfo.Name); UPLOAD('',Magicpath,'',FileInfo.Name,ServerFileName); EXIT(ServerFileName);
The trick to avoid the dialog box, is to use the Magicpath (which is simply the text ‘<TEMP>’) for the FromFolder parameter. This means that the RTC expects the file to exist in the RTC temp folder. Don’t use the UPLOAD statement with the Magicpath when the file is not existing in the RTC temp folder! It will throw an error on the server and the RTC connection with the Service Tier will be lost.
The steps that need to be done are:
- Find the RTC temp folder (a function is available in Codeunit 419)
- Check if the file is in the temp folder. If not, copy it to the temp folder
- Upload the file from the temp folder to the server
- Return the server path
I my eyes the UPLOAD function could use some improvements. Things that came to my mind:
The dialog box can be suppressed by using <TEMP> in the FromFolder parameter. However, then the file must also exist in the client temp folder. Why isn’t there an extra parameter ShowDialog? Than you can control the dialog and still have the option to upload a file from any location, whithout the need to copy it first to the client temp folder.
To find the RTC temp folder, the function ClientTempFileName first creates a temporary file on the server, then downloads it to the client and finds the path from the downloaded file. Wow, that’s making things complex! Why isn’t a global variable CLIENTTEMPPATH available?
Suggestions are posted to Connect. You can vote for it here: https://connect.microsoft.com/dynamicssuggestions/feedback/details/727910/improvements-for-upload-and-download-statement
Anyway, this code snippet makes life a little bit easier.