Dropzone and ASP.NET Image Uploader: Uploaded Image is blank and has Underscore Name and Larger Filesize

94 Views Asked by At

"I am developing an image uploader using Dropzone in ASP.NET. I am encountering an issue where, after clicking the submit button, the uploaded image file appearing in my directory is blank corrupt and has a "_" name and a filesize greater than the original size. link to the Image of the issue occuring.

For implementation I referred to this chunked image file upload link: Dropzone JS - Chunking

I have checked my frontend ASPX code for any issues, as well as the backend ChunkedUploaderHandler.ashx code which handles chunked image uploads, but I cannot identify the problem.

Could someone please guide me on what might be causing this issue and how to resolve it? I would appreciate any insights or suggestions.

Below are the relevant sections of my dropzone config and ChunkedUploaderHandler.ashx backend code for reference:

Thank you in advance for your help!"

Dropzone config:

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <script>
        $(document).ready(function () {
            Dropzone.autoDiscover = false;
            // Initialize Dropzone
            var myDropzone = new Dropzone("#Form1", {
                url: "ChunkedUploadHandler.ashx",
                autoProcessQueue: false, // Do not process the queue automatically
                //parallelUploads: 1, // Limit parallel uploads to 1
                maxFilesize: 1024, // Max individual file size 1024 MB
                chunking: true, // Enable chunking
                forceChunking: true, // Force chunking
                parallelChunkUploads: true, // Allow parallel chunk uploads
                chunkSize: 1000000, // Chunk size 1,000,000 bytes (~1MB)
                retryChunks: true, // Retry chunks on failure
                retryChunksLimit: 3, // Retry maximum of 3 times (default is 3)
                acceptedFiles: "image/*",
                clickable: ".dropzone",
                previewsContainer: "#previewsContainer",
                addRemoveLinks: true,
                params: function (files, xhr, chunk) {
                    if (chunk) {
                        return {
                            dzUuid: chunk.file.upload.uuid,
                            dzChunkIndex: chunk.index,
                            dzTotalFileSize: chunk.file.size,
                            dzCurrentChunkSize: chunk.dataBlock.data.size,
                            dzTotalChunkCount: chunk.file.upload.totalChunkCount,
                            dzChunkByteOffset: chunk.index * this.options.chunkSize,
                            dzChunkSize: this.options.chunkSize,
                            dzFilename: chunk.file.name,
                            eventID: $('#ContentPlaceHolder1_DropDownList1').val(),
                        };
                    }
                },
                chunksUploaded: function (file, done) {
                    // All chunks have been uploaded. Perform any other actions
                    var eventID = document.getElementById("ContentPlaceHolder1_DropDownList1").value; // Get user ID from dropdown
                    console.log(eventID)
                    var formData = {
                        dzUuid: file.upload.uuid,
                        dzFilename: file.name,
                        dzTotalFileSize: file.size,
                        dzTotalChunkCount: file.upload.totalChunkCount,
                        eventID: eventID
                    };
                    /*formData.append('eventID', $('#ContentPlaceHolder1_DropDownList1').val());*/

                    // Send data to server to merge chunks
                    $.ajax({
                        type: "PUT",
                        url: "ChunkedUploadHandler.ashx",
                        data: formData,
                        success: function (data) {
                            // Must call done() if successful
                            done();
                        },
                        error: function (msg) {
                            file.accepted = false;
                            myDropzone._errorProcessing([file], msg.responseText);
                        }
                    });
                },
                init: function () {
                    // Handle errors during upload
                    this.on('error', function (file, errorMessage) {
                        // Send request to delete temporary files created if upload failed or canceled
                        $.ajax({
                            type: "DELETE",
                            url: "ChunkedUploadHandler.ashx",
                            data: {
                                dzIdentifier: file.upload.uuid,
                                fileName: encodeURIComponent(file.name),
                                expectedBytes: file.size,
                                totalChunks: file.upload.totalChunkCount,
                                eventID: document.getElementById("ContentPlaceHolder1_DropDownList1").value // Get eventID from dropdown
                            },
                            success: function (data) {
                                // Handle success response
                            }
                        });
                    });
                }
            });

            // Handle form submission
            document.getElementById("btnUploadPhoto").addEventListener("click", function () {
                // Process the queue when upload button is clicked
                myDropzone.processQueue();
            });
        });

    </script>
</asp:Content>

ChunkedUploaderHandler.ashx Backend:

<%@ WebHandler Language="C#" Class="ChunkedUploadHandler" %>

using System;
using System.IO;
using System.Web;

public class ChunkedUploadHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string dzIdentifier = context.Request.QueryString["dzIdentifier"];
        string fileName = context.Request.QueryString["fileName"];
        string expectedBytes = context.Request.QueryString["expectedBytes"];
        string totalChunks = context.Request.QueryString["totalChunks"];
        string eventId = context.Request.QueryString["eventID"];

        string chunkDirectory = HttpContext.Current.Server.MapPath("~/Events/originals/" + eventId);
        Console.Write(chunkDirectory);

        if (!Directory.Exists(chunkDirectory))
        {
            Directory.CreateDirectory(chunkDirectory);
        }

        string filePath = Path.Combine(chunkDirectory, dzIdentifier + "_" + fileName);

        using (FileStream fs = new FileStream(filePath, FileMode.Append))
        {
            byte[] buffer = new byte[context.Request.InputStream.Length];
            context.Request.InputStream.Read(buffer, 0, buffer.Length);
            fs.Write(buffer, 0, buffer.Length);
        }

        int currentChunkIndex = int.Parse(context.Request["dzChunkIndex"]);

        // Check if all chunks have been uploaded
        if (currentChunkIndex + 1 == int.Parse(totalChunks))
        {
            // All chunks have been uploaded. Now, combine them to form the complete file.
            CombineChunks(chunkDirectory, dzIdentifier, fileName, int.Parse(totalChunks), int.Parse(expectedBytes));
        }
    }

    private void CombineChunks(string chunkDirectory, string dzIdentifier, string fileName, int totalChunks, int expectedBytes)
    {
        string finalFilePath = Path.Combine(chunkDirectory, fileName);

        using (FileStream finalFileStream = new FileStream(finalFilePath, FileMode.Create))
        {
            for (int i = 0; i < totalChunks; i++)
            {
                string chunkFilePath = Path.Combine(chunkDirectory, dzIdentifier + "_" + fileName);
                byte[] chunkData = File.ReadAllBytes(chunkFilePath);
                finalFileStream.Write(chunkData, 0, chunkData.Length);

                // Remove the chunk file after combining
                File.Delete(chunkFilePath);
            }
        }

        // Now, the file is complete. You can save it or perform further processing.
    }

    public bool IsReusable
    {
        get { return false; }
    }
}
0

There are 0 best solutions below