Description
Brief description of the issue
Cannot retrieve an uploaded file by the FileUpload field in a custom workflow, when deployed in Umbraco Cloud (locally it works).
Specifics
Umbraco 8.16.0
Forms 8.8.0
Deploy 4.1.4
Steps to reproduce
Create a form, with inside a FileUpload field, then implement a custom workflow, where the file uploaded by the FileUpload field type is retrieved using this code:
var file = record.ValueAsString("alias");
Expected result
"file" contains the right path to ...media\forms\upload... etc..
Actual result
"file" is empty when deployed in Umbraco Cloud (it contains the right path to media\forms\upload\ etc.. when executed locally).
Workaround
It seems that the issue is related to the ConvertToRecord method in FileUpload class, there is some code in that function that move the file between repositories, from a temporary repository to the media folder.
As a workaround, I created a custom field type and overrode that method (ConvertToRecord) with a custom one:
public override IEnumerable<object> ConvertToRecord(
Field field,
IEnumerable<object> postedValues,
HttpContextBase context)
{
var processed = new List<object>();
SetFileUploadPath(field, context);
foreach (var postedValue in postedValues)
{
if (postedValue != null && !string.IsNullOrEmpty(postedValue.ToString()))
{
var tempFilePathRelative = DecryptFilePath(postedValue.ToString());
var tempFilePathAbsolute = IOHelper.MapPath(tempFilePathRelative);
var filePathRelative = $"{_uploadPath}{Guid.NewGuid().ToString()}/{Path.GetFileName(tempFilePathRelative)}".ToLower(
CultureInfo.InvariantCulture);
var tempFormUploadPath = IOHelper.MapPath(Configuration.UploadTempPath);
if (File.Exists(tempFilePathAbsolute) && tempFilePathAbsolute.StartsWith(tempFormUploadPath))
{
var filePathAbsolute = IOHelper.MapPath(filePathRelative);
var directoryName = Path.GetDirectoryName(filePathAbsolute);
if (!string.IsNullOrWhiteSpace(directoryName) && !Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
var fileInfo = new FileInfo(tempFilePathAbsolute);
if (fileInfo.Directory != null && Directory.Exists(fileInfo.Directory.FullName))
{
File.Move(tempFilePathAbsolute, filePathAbsolute);
processed.Add(filePathRelative);
try
{
File.Delete(tempFilePathAbsolute);
if (!Directory.EnumerateFileSystemEntries(fileInfo.Directory.FullName).Any<string>())
{
Directory.Delete(fileInfo.Directory.FullName);
}
}
catch (Exception)
{
// ignored
}
}
}
else
processed.Add((object)tempFilePathRelative);
}
}
return (IEnumerable<object>)processed;
}
Basically I replaced the part where the file was copied using streams and IMediaFileSystem with File.Move().
Note: in this solution, mediafile system type is completely ignored.