我终于想出了如何将文件从 Angular 8 前端上传到 C# .Net Core 3.0 后端 API Controller 。但是为了得到我完全需要的东西,我还有一个类,它定义了需要传入的用户设置的文件内容(例如,标题行数、列值等......)。
在客户端,我只需创建一个 FormData 对象并将文件推送到其中,然后将其发送到后端。如果我只是发送此类然后在后端将其作为“IFormFileCollection”接收,这将非常有用。但是,如果我将 FormData 和我的附加类放在 Wrapper 类中,则会出现错误(发布在底部)。这里我贴出不起作用的代码。
这是我发送的客户端代码:
export interface FileProvider
{
formData: FormData;
testString: string;
}
然后我的 TypeScript 代码发送到后端:
async UploadFiles() {
try {
let files: File[] = this.files;
let myFormData: FormData = new FormData();
for (let i = 0; i < files.length; i++) {
let file: File = files[i];
myFormData.append('file', file, file.name);
}
/** Wrap this in a class. */
let fileProvider: FileProvider = {
formData: myFormData,
testString: "This is just a test string... but will be a class"
}
let promise = new Promise((resolve, reject) => {
this.dataService.UploadData(fileProvider).subscribe(data => resolve(data), error => reject(error))
});
let result = await promise;
alert("Successfully loaded Data");
}
catch (error) {
alert(error.message + ", Status: " + error.status + ", OK: " + error.ok + ", " + error.error);
}
}
我的小DataService post方法:
UploadData(fileProvider: FileProvider) {
let path: string = this.api + 'wells/formdata';
return this.http.post(path, fileProvider);
}
还有我的 C# .Net Core 3 后端 Controller 代码:
[Serializable]
public class FileProvider
{
public IFormCollection FormData { get; set; }
public string TestString { get; set; }
}
[HttpPost("formdata"), DisableRequestSizeLimit]
public IActionResult Upload(FileProvider fileProvider)
{
try
{
IFormFileCollection fileCollection = fileProvider.FormData.Files;
string testString = fileProvider.TestString;
foreach (IFormFile file in fileCollection)
{
/// Read at a line a time.
StringBuilder lineAtATime = new StringBuilder();
using (var reader = new StreamReader(file.OpenReadStream()))
{
while (reader.Peek() >= 0)
{
string line = reader.ReadLine();
lineAtATime.Append(line);
}
}
string textByLines = lineAtATime.ToString();
}
return Ok();
}
catch (Exception ex)
{
return StatusCode(500, "Internal server error: " + ex.Message);
}
}
最终抛出的错误如下:
"无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'Microsoft.AspNetCore.Http.IFormCollection' 因为该类型需要一个 JSON 数组(例如 [1,2,3])才能正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3])或更改反序列化类型,使其 是一个普通的 .NET 类型(例如,不是像整数这样的原始类型,不是像数组或列表这样的集合类型),可以 从 JSON 对象反序列化。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径 'formData',第 1 行,位置 14。”
我可以做些什么来传递两个参数类?
谢谢!!
最佳答案
原因是您在 multipart/form-data
中发送的是 类 json 对象 而不是有效负载 格式。从 JSON
不能表示二进制字节(文件),你永远不能这样。
如何解决:
而不是上传自定义 FileProvider
(json),只需 附加 testString
字段到 FormData
,然后上传FormData
直接。
服务器端
替换FormData
IList<IFormFile> Files
的属性(property):
[Serializable]public class FileProvider { public string TestString { get; set; }public IFormCollection FormData { get; set; }public IList<IFormFile> Files { get; set; } } public IActionResult Upload([FromForm]FileProvider fileProvider) { var files = fileProvider.Files; var testString = fileProvider.TestString; ... }
客户端
更改您的Service
接收参数FormData
类型:
UploadData(fileProvider: FileProvider) {UploadData(formdata: FormData) { let path: string = this.api+ 'wells/formdata'; return this.http.post(path, formdata); }
最后,将额外的字段附加到 FormData
直接:
async UploadFiles() { try { let files: File[] = this.files; let myFormData: FormData = new FormData(); for (let i = 0; i < files.length; i++) { let file: File = files[i];myFormData.append('file', file, file.name);myFormData.append('files', file, file.name); // the filed name is `files` because the server side declares a `Files` property } myFormData.append("testString", "This is just a test string... but will be a class"); // add extra fields // ... add more fields as you likelet fileProvider: FileProvider = { formData: myFormData, testString: "This is just a test string... but will be a class" } let promise = new Promise((resolve, reject) => { this.dataService.UploadData(fileProvider).subscribe(data => resolve(data), error => reject(error)) });let resp = await this.dataService.UploadData(myFormData).toPromise(); alert("Successfully loaded Data"); } catch (error) { alert(error.message + ", Status: " + error.status + ", OK: " + error.ok + ", " + error.error); } }
关于c# - 上传带有附加信息的文件(Angular 8 到 C# Core 3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58938944/