8

I'm making complex form And I want to use multiple (different) dropzone.js in order to upload files.

Here is how I made:

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
... form elements...
<div id="files" name="files" class="dropzone"></div>
}

And the JS:

Dropzone.options.files = {
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 100,
    maxFiles: 100,

    paramName: "file", // The name that will be used to transfer the file
    maxFilesize: 8, // MB
    url: "/pathToAction"
};

I want to send files and data of the form at the same time, all mapped to an object to the controller but dropzone needs to have the "url" in order to accept file upload... How to fix this? Maybe I can get the url of the form element and put it into the url parameter?

1
  • 1
    The way I have handled this case was by setting an upload method in my controller which saved locally all files on their upload. Then when the user submitted the form I just took the files and saved them where they needed to saved by their references. This way of course had some javascript handling when a file was deleted and I had to hold some discriminators for my files but it was something that worked for all types of files and is solid. If you are interested in such a way I could provide the code for this so let me know... Commented Dec 13, 2017 at 14:30

2 Answers 2

2

As i searched on the google, there is no way to send one request for multiple "dropzone" with the same URL, so i solved this problem manually by the following steps:

1) Dropzone actually change the images to Base64 string for thumbnail preview and then it add that string to the source of "img" tag. So you need to read that image "src" and "alt", and also add them to the input type hidden dynamically as the following:

    $('#btnUpload').on('click', function () {
        $.each($("img[data-dz-thumbnail]"), function( index, value ) {
            $('<input>').attr({
                type: 'hidden',
                name: 'myHiddenFiles[' + index + '].Key',
                value: $(value).attr("alt")
            }).appendTo('#newsForm');

            $('<input>').attr({
                type: 'hidden',
                name: 'myHiddenFiles[' + index + '].Value',
                value: $(value).attr("src")
            }).appendTo('#upload-Invoices');
        });
        $("#upload-Invoices").submit();
    });

Repeat this codes for each dropzone you need to post their data.

2) On your action method, you need to add a parameter with type "Dictionary" in order to get file name and file content with Base64 string format. Then you can parse the Base64 string as image, store it as a file and save your form data to the database. You can see the related snippet code as following:

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(ModelClass model, IDictionary<string, string> myHiddenFiles)
        {
            if (ModelState.IsValid)
            {
                foreach (var file in myHiddenFiles)
                {
                    var base64 = file.Value.Substring(file.Value.IndexOf(',') + 1).Trim('\0');
                    var bytes = Convert.FromBase64String(base64);

                    var saveFile = Server.MapPath("~/Images/" + file.Key);
                    System.IO.File.WriteAllBytes(saveFile, bytes);

                    // Save your model to database....
                }
            }
            return View();
        }
2
  • 1
    This could only work for images if I'm not mistaken. Commented Dec 13, 2017 at 14:31
  • that's an issue for me!
    – clement
    Commented Dec 14, 2017 at 8:45
-2

You an create the path to action with the @Url.Action helper

  ...
  paramName: "file", // The name that will be used to transfer the file
  maxFilesize: 8, // MB
  url: "@Url.Action("actionname")"
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.