public ActionResult Upload(MultipleUploadViewModel vm) { if (ModelState.IsValid) { if (vm.FileData != null && vm.FileData.Length > 0) { IList <FeedingSource> sources = new List <FeedingSource>(); // construct FeedingSources and gather validation errors if any for (int i = 0; i < vm.FileData.Length; i++) { if (vm.FileData[i] != null && vm.FileData[i].ContentLength > 0) { FeedingSource fs = this.ProcessUpload(vm, i); if (fs != null) { sources.Add(fs); } } } // save those without errors if (sources.Any()) { foreach (FeedingSource fs in sources) { this.feedingSourceTasks.SaveFeedingSource(fs); } TempData["SuccessfullyUploaded"] = sources; this.emailTasks.SendFeedingSourcesUploadedEmail(sources); } if (ModelState.IsValid) { return(RedirectToAction("Index")); } } } return(Upload()); }
protected FeedingSource ProcessUpload(MultipleUploadViewModel vm, int index) { // we use this flag instead of ModelState.IsValid because we need to reset this value for every file; ModelState.IsValid is a single flag for all uploaded files. bool hasError = false; using (Stream fileStream = vm.FileData[index].InputStream) { // Progressively check for duplicates, most reliable check first. Only return one duplicate validation error if any. // check Source hash duplicate string hash = BitConverter.ToString(MD5.Create().ComputeHash(fileStream)).Replace("-", ""); IList <SourceDTO> dtos = this.sourceTasks.GetSources(hash); if (dtos != null && dtos.Count > 0) { hasError = true; ModelState.AddModelError( "FileData", "An identical source (<a href='" + Url.Action("Index", "Sources", new { area = "Profiling" }) + "#info/" + dtos.First().SourceID + "' target='_blank'>" + dtos.First().SourceName + "</a>) exists already with Source ID of " + dtos.First().SourceID + "." ); } else { // check Source name duplicate Source s = this.sourceTasks.GetSource(vm.FileData[index].FileName); if (s != null) { hasError = true; ModelState.AddModelError( "FileData", "<a href='" + Url.Action("Index", "Sources", new { area = "Profiling" }) + "#info/" + s.Id + "' target='_blank'>" + s.SourceName + "</a> exists already with Source ID of " + s.Id + ". If you're sure you have a different file, rename it before uploading." ); } else { // check FeedingSource name duplicate FeedingSource fs = this.feedingSourceTasks.GetFeedingSource(vm.FileData[index].FileName); if (fs != null) { hasError = true; ModelState.AddModelError( "FileData", "<a href='" + Url.Action("Details", "Feeding", new { area = "Sources", id = fs.Id }) + "' target='_blank'>" + vm.FileData[index].FileName + "</a> was already uploaded; delete it or change your file name." ); } } } AdminUser user = this.userTasks.GetAdminUser(User.Identity.Name); if (user == null) { hasError = true; ModelState.AddModelError("UploadedBy", "Logged-in user doesn't appear to be exist."); } if (vm.IsReadOnly && string.IsNullOrEmpty(vm.UploadNotes)) { hasError = true; ModelState.AddModelError("UploadNotes", "Read-only sources should have a justification in the notes."); } if (!hasError) { FeedingSource fs = new FeedingSource(); fs.Name = Path.GetFileName(vm.FileData[index].FileName); fs.Restricted = vm.Restricted; fs.IsReadOnly = vm.IsReadOnly; fs.IsPublic = vm.IsPublic; fs.FileModifiedDateTime = vm.FileModifiedDateTime != null && vm.FileModifiedDateTime[index] != null ? vm.FileModifiedDateTime[index] : DateTime.Now; fs.UploadedBy = user; fs.UploadDate = DateTime.Now; fs.UploadNotes = vm.UploadNotes; if (!string.IsNullOrEmpty(vm.AuthorIds)) { string[] ids = vm.AuthorIds.Split(','); foreach (string id in ids) { int result; if (int.TryParse(id, out result)) { SourceAuthor a = this.sourcePermissionTasks.GetSourceAuthor(result); if (a != null) { fs.SourceAuthors.Add(a); } } } } if (!string.IsNullOrEmpty(vm.OwnerIds)) { string[] ids = vm.OwnerIds.Split(','); foreach (string id in ids) { int result; if (int.TryParse(id, out result)) { SourceOwningEntity e = this.sourcePermissionTasks.GetSourceOwningEntity(result); if (e != null) { fs.SourceOwningEntities.Add(e); } } } } fileStream.Position = 0; // we read the stream earlier when computing hash MemoryStream memoryStream = fileStream as MemoryStream; if (memoryStream == null) { memoryStream = new MemoryStream(); fileStream.CopyTo(memoryStream); } fs.FileData = memoryStream.ToArray(); return(fs); } return(null); } }