【问题标题】:Why is IFormFile collection empty when sent from Dropzone.js?为什么从 Dropzone.js 发送的 IFormFile 集合为空?
【发布时间】:2018-06-18 12:53:19
【问题描述】:

我正在尝试使用 Dropzone.js 将 IFormFile(图像)集合发送到以下 ASP.NET Core 2.1 Api 控制器操作:

    [HttpPost("[action]")]
    public async Task<IActionResult> Upload([FromForm] ICollection<IFormFile> files)
    { ... }

我能够从 Postman 成功地将文件发送到此 Api。但我无法让它从实现 Dropzone 的 UI 发送文件。我在 Razor 页面中使用 ASP 表单

    <div>
        <form action="/api/images/upload"
              class="dropzone needsclick dz-clickable"
              id="image-upload"
              method="post"
              enctype="multipart/form-data">
            <div class="dz-message needsclick">
                <span class="note needsclick">
                    Drop files here or click to upload.
                </span>
            </div>
        </form>
    </div>

使用以下 Dropzone 实现

/* Dropzone */
// "imageUpload" is the camelized version of the HTML element's ID
Dropzone.options.imageUpload = {
    paramName: "files", // The name that will be used to transfer the file
    dictDefaultMessage: "Drop files here or Click to Upload",
    addRemoveLinks: true, // Allows for cancellation of file upload and remove thumbnail
    init: function() {
        myDropzone = this;
        myDropzone.on("success", function(file, response) {
            console.log("Success");
            myDropzone.removeFile(file);
        });                    
    }
};

此设置 - 以及类似的变体 - 将 空集合发送到 Api,如屏幕截图所示:

我已经尝试过在此处发布的类似问题中的解决方案(例如 thisthis)。我也尝试过调整表单设置和 Dropzone 配置。我尝试过的一切都没有奏效。正如我在上面提到的,我可以从 Postman 发布到 Api,所以我怀疑问题出在我的 UI 设置上。有人可以帮忙吗?

更新:

    <div class="box content">
        <hr>
        <h2>Upload photos</h2>
        <div>
            <form action="/api/images/upload"
                  class="dropzone needsclick dz-clickable"
                  id="image-upload"
                  method="post"
                  enctype="multipart/form-data">
                <div class="dz-message needsclick">
                    <span class="note needsclick">
                        Drop files here or click to upload.
                    </span>
                </div>
            </form>
        </div>
        <h2>Generated Thumbnails</h2>
        <!-- <p><span id="gallery-note">Gallery refreshes from storage container image links every 5 seconds.</span></p> -->
        <div id="stored-images"></div>
        <!-- The Gallery as inline carousel, can be positioned anywhere on the page -->
        <div id="blueimp-gallery-carousel" class="blueimp-gallery blueimp-gallery-carousel">
            <div class="slides"></div>
            <h3 class="title"></h3>
            <a class="prev">‹</a>
            <a class="next">›</a>
            <a class="play-pause"></a>
            <ol class="indicator"></ol>
        </div>
    </div>

    <div class="box footer">
        <hr>
        <div class="privacy">

        </div>
    </div>
</main>


@section scripts {
    <script>
        // init gallery for later use
        var gallery;

        // Grab links for images from backend api
        function fetchImageLinks() {
            // Fetch images
            //alert("1");
            //http://localhost:61408/api/Images/thumbnails
            $.get("/api/Images/thumbnails", function (fetchedImageLinks) {
                //alert("2");
                console.log(fetchedImageLinks)

                // Check if anything is in there
                if (_.isEmpty(fetchedImageLinks)) {
                    console.log('empty fetched')
                    // do nothing
                } else {
                    // Check if we have a gallery initialized
                    if (_.isEmpty(gallery)) {
                        // initialize gallery
                        gallery = blueimp.Gallery(
                            fetchedImageLinks, // gallery links array
                            {
                                container: '#blueimp-gallery-carousel',
                                carousel: true
                            } // gallery options
                        );
                    } else {
                        // check if images are equal to array
                        console.log('currently in gallery:')
                        console.log(gallery.list)
                        var imageLinksEqual = _.isEqual(_.sortBy(gallery.list.map(s => s.split("?")[0])), _.sortBy(fetchedImageLinks.map(s => s.split("?")[0])))
                        if (imageLinksEqual) {
                            console.log('images arr are equal')
                            // do nothing
                        } else {
                            console.log('images arr are not equal')

                            // update gallery with new image urls. Only compare actual url without SAS token query string
                            var newImageLinks = _.difference(fetchedImageLinks.map(s => s.split("?")[0]), gallery.list.map(s => s.split("?")[0]))

                            console.log('differene is: ')
                            console.log(newImageLinks)
                            // Only add new images
                            gallery.add(newImageLinks);

                            // Force image load
                            gallery.next();
                        }
                    }
                }
            });
        }

        // Start first interval
        fetchImageLinks()

        setInterval(function () {
            fetchImageLinks()
        }, 5000)

        function myParamName() {
            return "files";
        }
        /* Dropzone */
        // "imageUpload" is the camelized version of the HTML element's ID
        Dropzone.options.imageUpload = {
            paramName: "files", // The name that will be used to transfer the file
            //uploadMultiple: true,
            //paramName: myParamName,
            dictDefaultMessage: "Drop files here or Click to Upload",
            addRemoveLinks: true, // Allows for cancellation of file upload and remove thumbnail
            init: function () {
                myDropzone = this;
                myDropzone.on("success", function (file, response) {
                    console.log("Success");
                    myDropzone.removeFile(file);
                });
            }
        };

    </script>
}

【问题讨论】:

    标签: asp.net-core dropzone.js asp.net-core-webapi


    【解决方案1】:

    检查您的拖放区设置是否正确应用。我已经按原样尝试了您的代码,它对我来说效果很好。但是,如果我从页面中删除了 Dropzone 配置,那么我得到的文件数为 0。

    要解决此问题,请将 dropzone 配置放入包含 dropzone 的 .cshtml 页面中,您应该会看到它运行正常,例如:

    索引.cshtml

    <div>
        <form action="/api/images/upload"
              class="dropzone needsclick dz-clickable"
              id="image-upload"
              method="post"
              enctype="multipart/form-data">
            <div class="dz-message needsclick">
                <span class="note needsclick">
                    Drop files here or click to upload.
                </span>
            </div>
        </form>
    </div>
    
    @section Scripts {
    <script>
        /* Dropzone */
        // "imageUpload" is the camelized version of the HTML element's ID
        Dropzone.options.imageUpload = {
            paramName: "files", // The name that will be used to transfer the file
            dictDefaultMessage: "Drop files here or Click to Upload",
            addRemoveLinks: true, // Allows for cancellation of file upload and remove thumbnail            
            init: function () {
                myDropzone = this;
                myDropzone.on("success", function (file, response) {
                    console.log("Success");
                    myDropzone.removeFile(file);
                });
            }
        };
    </script>
    }
    

    现在,如果您从页面中删除 @section,当您尝试上传文件时,您将开始收到 0 的 files.count

    如果您想将 dropzone 配置放在单独的文件中,那么您需要确保将其正确加载到页面中,例如将您的脚本部分更改为:

    @section scripts {
        <script src="~/scripts/dropzone-config.js"></script>
    }
    

    ...使用正确的放置区配置文件路径

    【讨论】:

    • 感谢您的回答。这真让人生气。我已经发布了上面的完整代码,并确保您的建议已得到实施。不幸的是我仍然有同样的问题。我错过了什么吗? (我在浏览器控制台中没有看到任何错误,这表明所有正确的库都已加载)。
    • 我还将所有 JavaScript 移动到外部文件,如下所示:'@section scripts { ' }
    • 我可以在 IE11 中重现该问题,所以我假设是您的浏览器?调试器说你的 scipt 中有几行有错误 - 以 var imageLinksEqual =...var imageLinksEqual =... 开头的那些行如果我将这些行注释掉,它就可以工作。
    • 感谢您的帮助。我从控制器中删除了 [ApiController] 属性。我不确定为什么会影响 POST 操作。再次感谢您的 cmets。 :)
    猜你喜欢
    • 2015-05-22
    • 1970-01-01
    • 2023-01-02
    • 2016-05-11
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多