无法使用多个对象将文件从 React 上传到 .net Core 5
Cannot upload files from React to .net Core 5 with multiple objects
我正在尝试上传包含多个对象的文件,例如我有一个学生想要上传多个 scanned/downloaded 文件。一切都必须拖放,所以当用户拖放文件时,我在反应应用程序中生成对象,并通过 axois post 和 _header["Content-Type"] = "multipart/form-data" 生成对象。 =23=].
但是我在发送的对象中看不到文件。我错过了什么?
public class CourseFile{
public Guid StudentId{get;set;}
public string FileName{get;set;}
public boolean IsPdf{get;set;}
public IFormFile File{get;set;}
}
学生控制器
[Route("upload-files")]
[HttpPost]
public async Task<IActionResult> UploadFiles([FromForm] IList<CourseFile> models)
{
var _req = Request;
var files = Request.Form.Files; // I can see files here
var file = files.First();
var modelProperty = file.Name; // I can see model property here
foreach (var courseFile in models)
{
UploadFiles(courseFile.File) // Always null
}
}
React 代码仅制作对象
private getFormData(data: any, form: FormData, idx = -1, baseKey = "") {
if (Array.isArray(data))
data.forEach((item, idx) => this.getFormData(item, form, idx));
Object.keys(data).forEach((key) => {
if (!key) return;
let _key =
idx > -1
? baseKey
? key.indexOf("files") >= 0
? `${baseKey}[][${key}]`
: `${baseKey}[${idx}][${key}][]`
: `${key}[${idx}]`
: key;
let itemData = data[key];
if (Array.isArray(itemData)) {
itemData.forEach((item, idx) => this.getFormData(item, form, idx, key));
return form;
}
if (key.indexOf("files") >= 0) {
form.append(`${baseKey}[${idx}][File][]`, itemData);
} else if (itemData) {
form.append(_key, itemData);
} else {
form.append(_key, "");
}
});
return form;
}
您的问题可能出在这里:
form.append(`${baseKey}[${idx}][File][]`, itemData);
key/name 似乎对文件很挑剔。为了工作,我最终不得不将其更改为以下内容:
form.append(`${baseKey}[${idx}].File`, itemData);
我制作了您的代码的简化版本(见下文)来进行测试。我尝试了多种组合,例如您有 [File][]
、[File]
,最后是 .File
。最后一个是唯一导致文件被正确设置的。
*编辑:这似乎只适用于 IFormFile
键。我能够做到 [StudentId]
或 .StudentId
,并且其中任何一个都可以。
获取代码:
const baseKey = 'models';
const data = new FormData();
for (let idx = 0; idx < 10; idx++) {
const b = new Blob(['This is my blob content ' + idx], { type: 'text/plain' });
data.append(`${baseKey}[${idx}].StudentId`, idx);
data.append(`${baseKey}[${idx}].File`, b);
}
fetch('/home/uploadfiles', { method: 'post', body: data });
控制器方法:
public class CourseFile
{
public int StudentId { get; set; }
public IFormFile File { get; set; }
}
public async Task<IActionResult> UploadFiles([FromForm] IList<CourseFile> models)
{
return Ok();
}
我正在尝试上传包含多个对象的文件,例如我有一个学生想要上传多个 scanned/downloaded 文件。一切都必须拖放,所以当用户拖放文件时,我在反应应用程序中生成对象,并通过 axois post 和 _header["Content-Type"] = "multipart/form-data" 生成对象。 =23=].
但是我在发送的对象中看不到文件。我错过了什么?
public class CourseFile{
public Guid StudentId{get;set;}
public string FileName{get;set;}
public boolean IsPdf{get;set;}
public IFormFile File{get;set;}
}
学生控制器
[Route("upload-files")]
[HttpPost]
public async Task<IActionResult> UploadFiles([FromForm] IList<CourseFile> models)
{
var _req = Request;
var files = Request.Form.Files; // I can see files here
var file = files.First();
var modelProperty = file.Name; // I can see model property here
foreach (var courseFile in models)
{
UploadFiles(courseFile.File) // Always null
}
}
React 代码仅制作对象
private getFormData(data: any, form: FormData, idx = -1, baseKey = "") {
if (Array.isArray(data))
data.forEach((item, idx) => this.getFormData(item, form, idx));
Object.keys(data).forEach((key) => {
if (!key) return;
let _key =
idx > -1
? baseKey
? key.indexOf("files") >= 0
? `${baseKey}[][${key}]`
: `${baseKey}[${idx}][${key}][]`
: `${key}[${idx}]`
: key;
let itemData = data[key];
if (Array.isArray(itemData)) {
itemData.forEach((item, idx) => this.getFormData(item, form, idx, key));
return form;
}
if (key.indexOf("files") >= 0) {
form.append(`${baseKey}[${idx}][File][]`, itemData);
} else if (itemData) {
form.append(_key, itemData);
} else {
form.append(_key, "");
}
});
return form;
}
您的问题可能出在这里:
form.append(`${baseKey}[${idx}][File][]`, itemData);
key/name 似乎对文件很挑剔。为了工作,我最终不得不将其更改为以下内容:
form.append(`${baseKey}[${idx}].File`, itemData);
我制作了您的代码的简化版本(见下文)来进行测试。我尝试了多种组合,例如您有 [File][]
、[File]
,最后是 .File
。最后一个是唯一导致文件被正确设置的。
*编辑:这似乎只适用于 IFormFile
键。我能够做到 [StudentId]
或 .StudentId
,并且其中任何一个都可以。
获取代码:
const baseKey = 'models';
const data = new FormData();
for (let idx = 0; idx < 10; idx++) {
const b = new Blob(['This is my blob content ' + idx], { type: 'text/plain' });
data.append(`${baseKey}[${idx}].StudentId`, idx);
data.append(`${baseKey}[${idx}].File`, b);
}
fetch('/home/uploadfiles', { method: 'post', body: data });
控制器方法:
public class CourseFile
{
public int StudentId { get; set; }
public IFormFile File { get; set; }
}
public async Task<IActionResult> UploadFiles([FromForm] IList<CourseFile> models)
{
return Ok();
}