为什么从 Dropzone.js 发送时 IFormFile 集合为空?
Why is IFormFile collection empty when sent from Dropzone.js?
我正在尝试使用 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 发送一个 空集合,如屏幕截图所示:
我已经在此处尝试了 post 类似问题中的解决方案(例如 , or )。我还尝试调整表单设置和 Dropzone 配置。我尝试过的一切都没有奏效。正如我在上面提到的,我可以从 Postman post 到 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>
}
检查您的放置区设置是否正确应用。我已经按原样尝试了您的代码,对我来说效果很好。但是,如果我从页面中删除了 Dropzone 配置,那么我得到的文件数为 0。
要解决此问题,请将 dropzone 配置放入包含 dropzone 的 .cshtml 页面,您应该会看到它工作正常,例如:
Index.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,您将在尝试上传文件时开始获得 files.count
0。
如果您想将放置区配置放在单独的文件中,则需要确保它已正确加载到页面中,例如将您的脚本部分更改为:
@section scripts {
<script src="~/scripts/dropzone-config.js"></script>
}
...使用正确的放置区配置文件路径
我正在尝试使用 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 发送一个 空集合,如屏幕截图所示:
我已经在此处尝试了 post 类似问题中的解决方案(例如
更新:
<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>
}
检查您的放置区设置是否正确应用。我已经按原样尝试了您的代码,对我来说效果很好。但是,如果我从页面中删除了 Dropzone 配置,那么我得到的文件数为 0。
要解决此问题,请将 dropzone 配置放入包含 dropzone 的 .cshtml 页面,您应该会看到它工作正常,例如:
Index.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,您将在尝试上传文件时开始获得 files.count
0。
如果您想将放置区配置放在单独的文件中,则需要确保它已正确加载到页面中,例如将您的脚本部分更改为:
@section scripts {
<script src="~/scripts/dropzone-config.js"></script>
}
...使用正确的放置区配置文件路径