Search code examples
c#asp.netwebformsdropzone

Struggling with integrating DropZoneJS into a C# WebForms app


I am struggling to get DropZoneJS to work in my ASP.NET C# WebForms app, and I could use some help. I have the following code in a basic Master page:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="main.master.cs" Inherits="demo.main1" %>

<!DOCTYPE html>

<html>
<head runat="server">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/min/dropzone.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/min/dropzone.min.js"></script>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:ContentPlaceHolder ID="cpMain" runat="server">

            </asp:ContentPlaceHolder>
        </div>
    </form>
</body>
</html>

and I have the following ASP.NET ASPX page that uses it and is meant to use DropZoneJS to upload image files:

<%@ Page Title="" Language="C#" MasterPageFile="~/main.Master" AutoEventWireup="true" CodeBehind="main2.aspx.cs" Inherits="Pueblo411.main2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cpMain" runat="server">
    <h3>Example demonstrating how to upload files using jQuery Dropzone Plugin</h3>
    <form action="/main2.aspx" method="post" class="dropzone">
        <div class="fallback">
            <input type="file" name="file" multiple>
        </div>
    </form>

    <script>
        $(function () {
            var myFileUploadDropZone = new Dropzone(".dropzone", {
                url: "test.ashx",
                maxFiles: 15,
                maxFilesize: 5,
                acceptedFiles: ".png, .jpg, .gif, .pdf, .doc",
                addRemoveLinks: true,
                dictDefaultMessage: "Drop your files here or click to upload",
                dictFallbackMessage: "Your browser does not support drag & drop feature.",
                dictInvalidFileType: "Your uploaded file type is not supported.",
                dictFileTooBig: "File is too big ({{filesize}} MB). Max filesize: {{maxFilesize}} MB.",
                dictResponseError: "Server responded with {{statusCode}} code.",
                dictCancelUpload: "Cancel Upload",
                dictRemoveFile: "Remove",
                init: function () {
                    this.on("complete", function (file) {
                        this.removeFile(file);
                    });
                }
            });
        });
    </script>
</asp:Content>

When I execute the above page, this is what I get: Screenshot of output

So, I am confused about what I'm doing wrong here. Any help please?


Solution

  • Firstly, I can't imagine any use case in which the file uploading would be part of the master page.

    You can certainly consider dropping in the "cdn" references into the master page so you can enjoy use of the file uploader (dropzone) in any page.

    However, since a up-loader page is going to be a child and separate page (of that master page), then again, I think I would place the script reference into that ONE page.

    However, let's leave and assume you have the current existing "cdn" setup in master page.

    Now let's create a new page (a child as master in most cases).

    And let's setup the page to work with the uploads.

    Say this markup:

        <div id="myfiledropzone" class="dropzone">
            <div class="fallback">
                <input name="file" type="file" multiple="multiple" runat="server" />
                <asp:Label ID="lblFallbackMessage" runat="server" />
            </div>
        </div>
    
        <asp:Button ID="cmdUpLoad" runat="server" Text="Upload"
            CssClass="btn" />
    </div>
    
    <script type="text/javascript">
        Dropzone.options.myfiledropzone = {
            paramName: "file", // The name that will be used to transfer the file
            maxFilesize: 2, // MB
            url: "DropZoneLoader.ashx"
        };
    </script>
    

    Note how we have asp.net button, but it has no code stub. So, all it going to do is post-back for us.

    So, next up, in place of a web method in the current page (which I don't have nor can find a good example), then we have to add a "handler" for the up-load code.

    I'll assume we create this handler at the SAME folder level as our up-load page. (and thus not have to mess nor worry about the URL path names).

    Create (add) a new Http handler.

    This one:

    enter image description here

    And the code inside can be this:

        public void ProcessRequest(HttpContext context)
        {
            foreach (string s in context.Request.Files)
            {
                HttpPostedFile file = context.Request.Files[s];
    
                string fileName = file.FileName;
                string fileExtension = file.ContentType;
                string FileWithPath = "";
                if (!string.IsNullOrEmpty(fileName))
                {
                    fileExtension = Path.GetExtension(fileName);
                    FileWithPath = HttpContext.Current.Server.MapPath(@"~/UpLoadedFiles/") + fileName;
                    file.SaveAs(FileWithPath);
                }
            }
        }
    

    And that should do it.

    The result looks like this:

    enter image description here

    Above is a proof of working concept.

    Do NOT try and use a "form" tag inside of a existing web page that is a "child" of a master page. Multiple form tags are NOT allowed anyway.

    As noted, I apologize for NOT having a handy web method that could be dropped into the existing web page, but that just a huge failing of the drop zone community, not the asp.net community. However, adding that separate "new" http handler (which we should not have to do) does work. So, in above, we added an separate "new" page (http handler) called DropZoneLoader.ashx, and you have to do the same.

    Anyway, give the above a try. You could then perhaps start to add some "more" of your existing options you added to drop zone, but at least now you have a working "proof of concept".