"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; }
}
}