private async Task <UploadedFileViewModel> HandleSingleFile( byte[] fileData, string fileName, string dataProjectId, string uploaderInitials) { var extension = Path.GetExtension(fileName)?.ToLowerInvariant(); if (extension == null) { throw new Exception("File has no extension"); } var matchingFileHandlers = fileHandlers.ContainsKey(extension) ? fileHandlers[extension] : new List <IFileHandler>(); var dataBlob = DataBlobBuilder.FromByteArray(fileData, fileName); FileHandlingStatus fileStatus; if (await dataBlobDatabase.ExistsAsync(dataBlob.Id)) { fileStatus = FileHandlingStatus.AlreadyExists; } else { await dataBlobDatabase.StoreAsync(dataBlob); fileStatus = FileHandlingStatus.Success; } Dictionary <string, object> additionalInformation = null; if (matchingFileHandlers.Any(x => x.RequiresAdditionalInformation)) { var additionalInformationRequiringFileHandlers = matchingFileHandlers.Where(x => x.RequiresAdditionalInformation).ToList(); var requestResult = await RequestAdditionalInformation(additionalInformationRequiringFileHandlers, fileName); if (!requestResult.IsRequestCompleted) { return(UploadedFileViewModel.Failed(fileName, "Not enough information provided")); } additionalInformation = requestResult.AdditionalInformationObjects; } var rawDataReference = DataReference.FromIId(dataBlob); var fileViewModels = new List <IDerivedFileDataViewModel>(); var derivedDataReferences = new List <DataReference>(); foreach (var matchingFileHandler in matchingFileHandlers) { var fileHandlerType = matchingFileHandler.GetType().Name; var fileHandlerAdditionalInformation = additionalInformation.ContainsKey(fileHandlerType) ? additionalInformation[fileHandlerType] : null; var fileHandlerResult = await matchingFileHandler.Handle(fileData, fileName, dataProjectId, fileHandlerAdditionalInformation); fileViewModels.AddRange(fileHandlerResult.ViewModels); derivedDataReferences.AddRange(fileHandlerResult.DerivedDataReferences); } var uploadInfo = new DataProjectUploadInfo( uploaderInitials, DateTime.UtcNow, dataProjectId, rawDataReference, derivedDataReferences, fileName); await dataProjectUploadInfoDatabase.StoreAsync(uploadInfo); return(new UploadedFileViewModel( fileName, fileStatus, string.Empty, uploadInfo.Id, rawDataReference, derivedDataReferences, dataApiClient, fileViewModels, clipboard)); }