Как указать поведение обратной передачи с помощью Dropzone с формой MVC5

#c# #asp.net-mvc #dropzone

Вопрос:

Я пытался разработать приложение MVC 5 с загрузкой файлов Dropzone. У меня возникли проблемы с контролем обратной передачи формы из dropzone. Я нахожу документацию по dropzone очень тонкой на местах, и там не так много хорошего примера кода. Даже демонстрационная версия MVC на веб-сайте dropzone уже давно является мертвой ссылкой.

У меня есть контроллер MVC и представления для выполнения транзакций. Транзакции могут иметь или не иметь файлов, прикрепленных к их форме при создании.

Вот мой контроллер mvc, создающий метод обратной отправки

 [HttpPost]  [ValidateAntiForgeryToken]  public async Tasklt;ActionResultgt; Create(TransactionDto transaction, IEnumerablelt;HttpPostedFileBasegt; files)  {  _logger.Info("Create new transaction POST");  if (ModelState.IsValid)  {  _logger.Info("ModelState is valid");  var er = await _transactionService.AddTransaction(transaction, files);  if (!er.Success)  {  Response.StatusCode = 500;  return Json(er.Messages);  }  // Make sure to specify view name in indexc method. Dropzone can be a bit funny  return RedirectToAction("Index", "Transactions");  }  _logger.Info("ModelState is not valid");  await GetTransactionCreateSelectLists();  return View(transaction);  }  

Вот некоторые из моих js-кодов, лежащих в основе моего представления mvc

 Dropzone.autoDiscover = false; var existingImages = []; var selectedVendor; var errored = false;  $(document).ready(function () {   // The Confirm Asset Deletion Modal  var confirmFileDeletionModalElement = $("#confirm-delete-modal");   // The Confirm Asset Deletion Modal Confirm Button  var confirmFileDeletionButtonSelectorName = "#modal-delete-asset-button";   // The Parent Form Submit button selector name.  var submitButtonSelectorName = "#submit";   // If true, when deleting assets, a confirmation modal popup will appear  var confirmDeleteAssets = true;   // The url that the parent form posts back to  var dropzoneUploadUrl = `${window.applicationBaseUrl}Transactions/Create`;   // The url to load when the form has been submitted successfully.  var formCompletedRedirectUrl = `${window.applicationBaseUrl}Transactions`;   // The element selector name that dropzone uses to preview existing files  var dropzonePreviewsElementSelectorName = "#previews";   // The element selector name that dropzone uses to allow user to click to add new files  var dropzoneClickableElementSelectorName = "#dropzone-clickable";   $('#myDropzone').dropzone({  url: dropzoneUploadUrl,  autoProcessQueue: false,  uploadMultiple: true,  parallelUploads: 100,  maxFiles: 100,  maxFilesize: 100,  paramName: "files",  previewsContainer: dropzonePreviewsElementSelectorName,  clickable: dropzoneClickableElementSelectorName,  dictDefaultMessage: "",  dictRemoveFile: "Remove",  addRemoveLinks: true,  init: function () {  var myDropzone = this;   this.on("complete", function (file, response) {  if (errored) {  //errored = false;  return;  //window.location = `${window.applicationBaseUrl}Transactions`;  //if (file.xhr) {  // file.xhr.response  //}   } else {  window.location = formCompletedRedirectUrl;  }  });   this.on('error', function(file, response) {  //$(file.previewElement).find('.dz-error-message').text(response);  errored = true;  utilities.errorToast(response);  });   this.on("addedfile", file =gt; {  var preview = $(file.previewElement);  var ptr = existingImages.find(x =gt; x.Id === file.id);  if (ptr) { // Existing file  preview.append(`lt;divgt;lt;a class="dropzone-preview-image" style="text-decoration: none;" href="/${ptr.ServerFolderPath}/${ptr.FileName}" target="_blank" data-ParentId="${ptr.ParentId}", data-AssetId="${ptr.AssetId}", data-FileName="${ptr.FileName}", data-DeleteFileFromDisk="true" gt;lt;span class="fa fa-search"gt;lt;/spangt;amp;nbsp;Previewlt;/agt;lt;/divgt;`);  preview.append(`lt;divgt;lt;a class="dropzone-delete-image" style="text-decoration: none;" href="${ptr.Id}" data-ParentId="${ptr.ParentId}", data-AssetId="${ptr.AssetId}", data-FileName="${ptr.FileName}", data-DeleteFileFromDisk="true"gt;lt;span class="fa fa-trash-alt"gt;lt;/spangt;amp;nbsp;Deletelt;/agt;lt;/divgt;`);   // Get rid of auto remove button for existing images but use it for nmewly added images (addRemoveLinks: true)  $(preview).children().closest('.dz-remove').hide();  }  else {  var thumbNailPath = assetUtilities.getThumbnailPath(file);  $(file.previewElement).find(".dz-image img").attr("src", thumbNailPath);  }  });    $('#submit').on("click", function (e) {  // Validate form here if needed    if (myDropzone.getQueuedFiles().length gt; 0) {  e.preventDefault();  e.stopPropagation();  myDropzone.processQueue();    } else {  if (!errored) {  myDropzone.uploadFiles([]);  $('#myDropzone').submit();  }  }  });   //document.getElementById("submit").addEventListener("click", function handler(e) {  // if (myDropzone.getAcceptedFiles().length gt; 0) {  // e.currentTarget.removeEventListener(e.type, handler);  // e.preventDefault();  // e.stopPropagation();  // myDropzone.processQueue();  // }  //});   //$("#myDropzone").one("submit", function (event) {  // event.preventDefault();  // myDropzone.processQueue(); // Tell Dropzone to process all queued files.  // //window.location.href = `${window.applicationBaseUrl}Transactions`;  //});   // $(submitButtonSelectorName).on("click", function (e) {  // if (myDropzone.files.length gt; 0) {  // e.preventDefault();  // e.stopPropagation();  // myDropzone.processQueue();  // myDropzone.options.autoProcessQueue = true;  // }  // });  }  });   $("#DateTime").focus();   . . .     

Вы можете видеть из комментариев зеленого цвета, какие вещи я пробовал с dropzone. Мне нужно, чтобы dropzone вел себя следующим образом.

  1. If no files are attached to the form. Ignore dropzone queue and and just post back data as normal. Then return to the list view (List of items being created). If there is an error than I can handle it maybe with toastr etc
  2. If one or more files are are attached to the form and Postback is successful. Show user a success toast and then go back to the list view.
  3. If one or more files are are attached to the form and Postback is unsuccessful. Show user an error message using toastr or similar and do nothing.

Basically what I am trying to do is to create a comprehensive form that can allow file uploads but that also allows for no files and error handling. The behaviour I am experiencing is as follows

a. I add files to form on create. Dropzone completes the form submission, my data gets created and the files get uploaded. However dropzone does not revert back to the list view (formCompletedRedirectUrl). It just seems to reload the Create (GET) method.

b. If there’s a server side error in my post, I don’t see it in the UI. Sometimes dropzone will revert back to the list view, sometimes not. You can see where I have been trying all kinds of things here with events, error handling and private errored state variable etc.

Can anyone help me to achieve 1,2, and 3 above reliably please?