public ActionResult Edit(Dictionary <string, PatientFilesGroupViewModel> patientFilesGroups) { var kv = patientFilesGroups.Single(); var formModel = kv.Value; PatientFileGroup dbFileGroup; if (formModel.Id == null) { Debug.Assert(formModel.PatientId != null, "formModel.PatientId != null"); dbFileGroup = new PatientFileGroup { PatientId = formModel.PatientId.Value, PracticeId = this.DbUser.PracticeId, CreatedOn = this.datetimeService.UtcNow, }; this.db.PatientFileGroups.AddObject(dbFileGroup); } else { dbFileGroup = this.db.PatientFileGroups .Include("PatientFiles") .Include("PatientFiles.FileMetadata") .FirstOrDefault(pe => pe.Id == formModel.Id); } Debug.Assert(dbFileGroup != null, "dbFileGroup != null"); var allExistingFilesInGroup = dbFileGroup.PatientFiles.ToDictionary(pf => pf.Id); var idsToKeep = new HashSet <int>(formModel.Files.Where(f => f.Id != null).Select(f => f.Id.Value)); var storageActions = new List <Action>(formModel.Files.Count); var metadataProvider = new DbFileMetadataProvider(this.db, this.datetimeService, this.DbUser.PracticeId); var metadataDic = metadataProvider.GetByIds(formModel.Files.Select(f => f.MetadataId).ToArray()).ToDictionary(f => f.Id); foreach (var eachFile in formModel.Files) { // Validating each file location... otherwise this could be a security hole. FileMetadata metadata; metadataDic.TryGetValue(eachFile.MetadataId, out metadata); if (metadata == null) { return(new StatusCodeResult(HttpStatusCode.NotFound, "Arquivo não encontrado. Outra pessoa deve ter removido esse arquivo neste instante.")); } var validContainer = string.Format("patient-files-{0}", this.DbUser.Id); if (metadata.ContainerName != validContainer) { throw new Exception("Invalid file location."); } PatientFile patientFile; if (eachFile.Id == null) { // creating and adding the new patient file Debug.Assert(formModel.PatientId != null, "formModel.PatientId != null"); patientFile = new PatientFile { FileMetadataId = metadata.Id, PatientId = formModel.PatientId.Value, PracticeId = this.DbUser.PracticeId, }; dbFileGroup.PatientFiles.Add(patientFile); // changing file metadata: // - it is not temporary anymore // - tag is free for another operation metadata.ExpirationDate = null; metadata.Tag = null; } else if (!allExistingFilesInGroup.TryGetValue(eachFile.Id.Value, out patientFile)) { return(new StatusCodeResult(HttpStatusCode.NotFound, "Arquivo não encontrado. Outra pessoa deve ter removido esse arquivo neste instante.")); } Debug.Assert(patientFile != null, "patientFile != null"); patientFile.Title = eachFile.FileTitle; } // deleting files that were removed foreach (var patientFileKv in allExistingFilesInGroup) { if (!idsToKeep.Contains(patientFileKv.Key)) { // create delegate to kill the file metadata and the storage blob // this is going to be called latter var metadata = patientFileKv.Value.FileMetadata; Action removeFile = () => TempFileController.DeleteFileByMetadata(metadata, this.db, this.storage); storageActions.Add(removeFile); // delete patient file (note that changes are not being saved yet) this.db.PatientFiles.DeleteObject(patientFileKv.Value); } } if (formModel.Files.Count == 0) { this.ModelState.AddModelError(string.Format("PatientFilesGroups[{0}].Files", kv.Key), "Deve haver pelo menos um arquivo na lista."); } if (this.ModelState.IsValid) { dbFileGroup.GroupTitle = formModel.Title; dbFileGroup.GroupNotes = formModel.Notes; Debug.Assert(formModel.FileGroupDate != null, "formModel.FileGroupDate != null"); dbFileGroup.FileGroupDate = this.ConvertToUtcDateTime(formModel.FileGroupDate.Value); Debug.Assert(formModel.ReceiveDate != null, "formModel.ReceiveDate != null"); dbFileGroup.ReceiveDate = this.ConvertToUtcDateTime(formModel.ReceiveDate.Value); dbFileGroup.Patient.IsBackedUp = false; this.db.SaveChanges(); // moving files that are stored in a temporary location foreach (var moveAction in storageActions) { moveAction(); } return(this.View("Details", GetViewModel(this.storage, dbFileGroup, this.DbUser.Id, this.GetToLocalDateTimeConverter()))); } FillMissingInfos(formModel, this.db.FileMetadatas); FillFileLengths(this.storage, formModel, this.DbUser.Id); this.ViewBag.FilesStatusGetter = (FilesStatusGetter)this.GetFilesStatus; return(this.View("Edit", formModel)); }
/// <summary> /// Upload whole file. /// </summary> /// <param name="prefix"> The prefix of the fields to be placed in the HTML. </param> /// <param name="location"> The location where the temporary file should be stored. </param> /// <returns> The <see cref="ActionResult"/> containing information about execution of the upload. </returns> private ActionResult UploadWholeFile(string prefix, string location, string tag) { var statuses = new List <FilesStatus>(); for (int i = 0; i < this.Request.Files.Count; i++) { var file = this.Request.Files[i]; Debug.Assert(file != null, "file != null"); var containerName = location.Split("\\".ToCharArray(), 2).FirstOrDefault(); var sourceFileName = Path.GetFileName(file.FileName ?? "") ?? ""; var normalFileName = StringHelper.NormalizeFileName(sourceFileName); var fileNamePrefix = location.Split("\\".ToCharArray(), 2).Skip(1).FirstOrDefault(); var fileExpirationDate = this.datetimeService.UtcNow + TimeSpan.FromDays(file.ContentLength < 10 * 1024000 ? 2 : 10); Debug.Assert(sourceFileName != null, "sourceFileName != null"); var metadataProvider = new DbFileMetadataProvider(this.db, this.datetimeService, this.DbUser.PracticeId); // creating the metadata entry for the main file FileMetadata metadata = metadataProvider.CreateTemporary( containerName, sourceFileName, string.Format("{0}file-{1}-{2}", fileNamePrefix, "{id}", normalFileName), fileExpirationDate, this.DbUser.Id, tag, formatWithId: true); metadata.OwnerUserId = this.DbUser.Id; metadataProvider.SaveChanges(); // saving the file to the storage this.storage.UploadFileToStorage(file.InputStream, containerName, metadata.BlobName); // returning information to the client var fileStatus = new FilesStatus(metadata.Id, sourceFileName, file.ContentLength, prefix); bool imageThumbOk = false; try { var fullStoragePath = string.Format("{0}\\{1}", containerName, metadata.BlobName); var thumbName = string.Format("{0}\\{1}file-{2}-thumb-{4}x{5}-{3}", containerName, fileNamePrefix, metadata.Id, normalFileName, 120, 120); var thumbResult = ImageHelper.TryGetOrCreateThumb(metadata.Id, 120, 120, fullStoragePath, thumbName, true, this.storage, metadataProvider); if (thumbResult.Status == CreateThumbStatus.Ok) { fileStatus.ThumbnailUrl = @"data:" + thumbResult.ContentType + ";base64," + Convert.ToBase64String(thumbResult.Data); fileStatus.IsInGallery = true; imageThumbOk = true; } } // ReSharper disable EmptyGeneralCatchClause catch // ReSharper restore EmptyGeneralCatchClause { } if (!imageThumbOk) { if (StringHelper.IsDocumentFileName(sourceFileName)) { fileStatus.IconClass = "document-file-icon"; } else { fileStatus.IconClass = "generic-file-icon"; } } else { fileStatus.UrlLarge = this.Url.Action("Image", new { w = 1024, h = 768, location, metadata.Id }); } fileStatus.UrlFull = this.Url.Action("File", new { location, metadata.Id }); fileStatus.DeleteUrl = this.Url.Action("Index", new { location, metadata.Id }); statuses.Add(fileStatus); } return(this.JsonIframeSafe(new { files = statuses })); }
public FilesStatus GetFilesStatus(PatientFileViewModel fileModel, string prefix) { var fileName = fileModel.SourceFileName; var containerName = fileModel.ContainerName; var sourceFileName = Path.GetFileName(fileModel.SourceFileName ?? "") ?? ""; var normalFileName = StringHelper.RemoveDiacritics(sourceFileName.ToLowerInvariant()); var fileNamePrefix = Path.GetDirectoryName(fileModel.BlobName) + "\\"; var fullStoragePath = string.Format("{0}\\{1}file-{2}-{3}", containerName, fileNamePrefix, fileModel.Id, normalFileName); var fileStatus = new FilesStatus(fileModel.Id, fileModel.MetadataId, fileName, fileModel.FileLength, prefix, fileModel.FileTitle); var isPatientFiles = Regex.IsMatch(fileModel.ContainerName, @"^patient-files-\d+$"); // Validating each file location... otherwise this could be a security hole. if (!isPatientFiles) { throw new Exception("Invalid file location for patient files."); } var fileMetadataProvider = new DbFileMetadataProvider(this.db, this.datetimeService, this.DbUser.PracticeId); bool imageThumbOk = false; try { var thumbName = string.Format("{0}\\{1}file-{2}-thumb-{4}x{5}-{3}", containerName, fileNamePrefix, fileModel.MetadataId, normalFileName, 120, 120); var thumbResult = ImageHelper.TryGetOrCreateThumb(fileModel.MetadataId, 120, 120, fullStoragePath, thumbName, true, storage, fileMetadataProvider); if (thumbResult.Status == CreateThumbStatus.Ok) { fileStatus.ThumbnailUrl = @"data:" + thumbResult.ContentType + ";base64," + Convert.ToBase64String(thumbResult.Data); fileStatus.IsInGallery = true; imageThumbOk = true; } } // ReSharper disable EmptyGeneralCatchClause catch // ReSharper restore EmptyGeneralCatchClause { } if (!imageThumbOk) { if (StringHelper.IsDocumentFileName(fileName)) { fileStatus.IconClass = "document-file-icon"; } else { fileStatus.IconClass = "generic-file-icon"; } } bool isTemp = fileModel.Id == null; if (isTemp) { var location = string.Format("{0}\\{1}", fileModel.ContainerName, fileModel.BlobName); if (imageThumbOk) { fileStatus.UrlLarge = this.Url.Action("Image", "TempFile", new { w = 1024, h = 768, id = fileModel.MetadataId, location }); } fileStatus.UrlFull = this.Url.Action("File", "TempFile", new { id = fileModel.MetadataId, location }); } else { if (imageThumbOk) { fileStatus.UrlLarge = this.Url.Action("Image", "PatientFiles", new { w = 1024, h = 768, id = fileModel.Id }); } fileStatus.UrlFull = this.Url.Action("File", "PatientFiles", new { id = fileModel.Id }); } return(fileStatus); }