D365FO Use of FileUpload control to Read CSV file
In Dynamics Ax implementation very often we get requirement
to upload data using csv files. Although
in Dynamics 365 for operations it can be easily done using data entities
and data packages, in this blog we will see how can we use new FileUpload
control and design classes to read, download files.
In Dynamics 365 for operations
application runs on cloud and the client is in web , so Microsoft
has introduce new process to read files using Azure blob. When we upload file,
that file gets uploaded to Azure blob and we have to read that file from Azure
blob to retrieve data.
Design classes:
There are two main types of classes that developers can work
with for the file upload control:
- Upload strategy class – This class lets developers control various parameters that should be enforced for uploaded files, such as the types of files that a user can upload and the maximum size of a file. It also lets developers determine where and how the uploaded file should be stored.All upload strategy classes must inherit from the abstract FileUploadStrategyBaseclass. The framework provides a default upload strategy class named FileUploadTemporaryStorageStrategy
- Upload result class – This
class lets developers access the details of a file that was uploaded by a
user, such as its name, content type, and upload status. It also lets
developers open and delete the corresponding file. All upload result
classes must inherit from the abstract FileUploadResultBase class. Default upload result class
that is named FileUploadTemporaryStorageResult.
This upload result class stores uploaded files to the temporary blob
storage and provides a download URL.
Below is X++ code to create dialog which uploads file in to blob
storage and get temporary URL to
retrieve data from the file.
public Object dialog()
{
DialogGroup dialogGroup;
FormBuildControl formBuildControl;
FileUploadBuild dialogFileUpload;
Set enumSet = new Set(Types::Enum);
;
dialog = super();
dialogGroup = dialog.addGroup("File path");
formBuildControl = dialog.formBuildDesign().control(dialogGroup.name());
dialogFileUpload = formBuildControl.addControlEx(classstr(FileUpload), FileUploadName);
dialogFileUpload.style(FileUploadStyle::MinimalWithFilename);
dialogFileUpload.baseFileUploadStrategyClassName(classstr(FileUploadTemporaryStorageStrategy));
dialogFileUpload.fileTypesAccepted(availableTypes);
dialogFileUpload.fileNameLabel("@SYS308842");
return dialog;
}
You can see in the above code I used FileUploadBuild control and provided base class FileUploadTemporaryStorageStrategy
to method baseFileUploadStrategyClassName which will be used to upload file to
azure blob.
The FileTypesAccepted property
of the file upload control lets you limit the types of files that users can
upload
dialogFileUpload.fileTypesAccepted(availableTypes);
availableTypes is private Variable declared in
classdeclaratoin
private str availableTypes = ".csv";
In the class Declaration control names for OK and upload
control
private const str OkButtonName = 'OkButton';
private const str
FileUploadName = 'FileUpload';
Following methods is required to Enables or disables the dialog Ok
button.
protected void
setDialogOkButtonEnabled(DialogRunbase _dialog, boolean _isEnabled)
{
FormControl okButtonControl = this.getFormControl(_dialog,
OkButtonName);
if (okButtonControl)
{
okButtonControl.enabled(_isEnabled);
}
}
protected FormControl getFormControl(DialogRunbase _dialog, str _controlName)
{
return
_dialog.formRun().control(_dialog.formRun().controlId( _controlName));
}
Once the file has been uploaded to blob storage ok button
needs to be enabled. Following method takes care of that by calling callback
event handler to be notified when upload is complete.
protected void uploadCompleted()
{
FileUpload fileUpload = this.getFormControl(dialog,
FileUploadName);
fileUpload.notifyUploadCompleted -= eventhandler(this.UploadCompleted);
textFile = fileUpload.fileName();
this.setDialogOkButtonEnabled(dialog,
true);
}
/// Disables the
dialog Ok button until the file upload is complete.
public void dialogPostRun(DialogRunbase _dialog)
{
FileUpload fileUpload = this.getFormControl(_dialog,
FileUploadName);
fileUpload.notifyUploadCompleted += eventhandler(this.uploadCompleted);
this.setDialogOkButtonEnabled(_dialog,
false);
}
Once dialog is
open you can see file upload control where you can select file and Ok button is
disabled.
Once file is uploaded to blob
Ok button is enabled, you can see that in below screen.
Here is the code which reads
the CSV file
void processCSVFile()
{
#File
container currentLine;
int totalOfLines;
CommaTextStreamIo localStream;
Num number;
FileUpload fileUploadControl = this.getFormControl(dialog,
FileUploadName);
FileUploadTemporaryStorageResult fileUploadResult =
fileUploadControl.getFileUploadResult();
if (fileUploadResult != null &&
fileUploadResult.getUploadStatus())
{
textFile =
fileUploadResult.getDownloadUrl();
}
localStream = CommaTextStreamIo::constructForRead(File::UseFileFromURL(textFile));
if (localStream.status()
!= IO_Status::Ok)
{
throw error(strfmt('Is not possible to open the file.
Error %1',enum2str(localStream.status())));
}
localStream.inFieldDelimiter("\,");
localStream.inRecordDelimiter("\n");
currentLine = localStream.read();
fileLineNumber++;
if(conlen(currentLine)
== 1)
{
throw error('Is not possible to import the file,
incorrect format');
}
currentLine = localStream.read();
fileLineNumber++;
while(currentLine)
{
number = conPeek(currentLine,1);
info(strFmt("Number :
%1",number));
currentLine = localStream.read();
}
}
Here is my Sample CSV file to
test the code
Infolog showing values of the
number column from csv file.
If you have any feedback feel free to comment. Thanks for
reading the blog and have a great day.
Reference:
very useful information, the post shared was very nice.
ReplyDeleteMicrosoft Dynamics Online Training