[英]Send form data from React to ASP.NET Core API
我编辑了整个问题,因为它很长而且令人困惑。
我将表单中的所有数据作为字符串化 JSON 发送,但现在我需要附加一个文件,所以我不能再这样做了。 如何以允许附加文件的格式将表单数据从 React 发送到 ASP.NET Core API?
我有几种工作正常的表单:我使用 React 中的 fetch 发送数据,并在我的 ASP.NET Core API 中正确接收它作为正文。
但是,我现在需要发送文件,而且我不知道如何附加它们,因为我只是将我的所有内容都发送到一个精简的 JSON 中。
fetch("localhost/api/test", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
我尝试发送这样构建的 FormData 对象而不是JSON.stringify(body)
。
let formData = new FormData();
for (var property in body) {
formData.append(property, body[property]);
}
但是当我发送这个对象而不是字符串化的 JSON 时,对于 ASP.NET Core 中的所有值,我总是得到 null。
我也试过发送这个:
URLSearchParams(data)
和这个:
let formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
我尝试了每种类型的数据编码的不同标头组合:
'Content-Type': 'multipart/formdata'
'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded'
我还尝试使用[FromBody]
和[FromForm]
从 ASP.NET 获取数据。
我想我已经尝试了上面解释过的所有选项的所有可能组合,但没有结果。 我总是在我的 API 中得到空值。
编辑:
现在,我什至没有尝试发送文件。 在尝试附加文件之前,我正在尝试以正确的格式成功发送通用数据。 我不知道我是否应该更改问题的标题。
这是我的 API 代码:
[HttpPost]
[Route("login")]
public object Login([FromBody] Credentials cred)
{
// check credentials
return CustomResult.Ok;
}
类Credentials
:
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
React 的对象body
如下所示:
{
username: "user",
password: "pass"
}
现在还有一点时间。 (捕获了 10 条鱼。)我从您的代码中注意到您使用了标题“multipart/formdata”,它应该有一个连字符; “多部分/表单数据”。
在我的 API 上,我指定它使用相同的类型: [Consumes("multipart/form-data")]
我不清楚 .net 核心默认值是什么以及它是否应该自动反序列化表单数据,但指定它应该排除任何歧义。
使用我的代码,我正在发送一个带有一些参数的文件。 在 api 方面,它看起来像:
public class FileUpload_Single
{
public IFormFile DataFile { get; set; }
public string Params { get; set; }
}
// POST: api/Company (Create New)
[HttpPost]
[Authorize(PermissionItem.SimulationData, PermissionAction.Post)]
[RequestSizeLimit(1024L * 1024L * 1024L)] // 1 Gb
[RequestFormLimits(MultipartBodyLengthLimit = 1024L * 1024L * 1024L)] // 1 Gb
[Consumes("multipart/form-data")]
public async virtual Task<IActionResult> Post([FromForm] FileUpload_Single data)
....然后在客户端它看起来像:
let formData = new FormData();
formData.append("DataFile", file);
formData.append("Params", JSON.stringify(params));
fetch(apicall, {
method: "POST",
mode: "cors",
headers: {
Authorization:
"Bearer " + (localStorage.getItem("token") || "").replace(/['"]+/g, ""),
Accept: "multipart/form-data",
},
body: formData,
})
文件来自
const changeHandler = (event) => {
setSelectedFile(event.target.files[0]);
setIsSelected(true);
};
(来自我的 React 组件)
我的整个问题都是一团糟,就我而言,问题在于for
循环。 但是,我将尝试清楚地解释我需要什么,因为网上有很多关于如何使用 React 将表单提交到 API 的误导性信息。
在后端,接受 POST 请求并使用FromForm
获取数据。 如果您需要使用凭据,最好通过标题传递它们,而不是将它们作为隐藏输入放在每个表单中。
[HttpPost]
[Route("test")]
public object Test([FromHeader] string token, [FromForm] MyDataClass data)
{
// check token
// do something with data
return CustomResult.Ok;
}
如果绑定对象,则属性必须与从前端发送的属性名称相同,并且必须具有公共 setter 。
public class MyDataClass
{
public string SomeInfo { get; set; }
public string SomeOtherInfo { get; set; }
}
将数据作为FormData
发送。 为此,您可以按照本教程进行操作。 这样,您无需担心在提交数据之前处理输入更改和格式化数据。
但是,如果您的数据已经在纯 JavaScript 对象中,您可以将其转换为FormData
,如下所示。
let formData = new FormData();
Object.keys(data).forEach(function (key) {
formData.append(key, data[key]);
});
尽管如此,这是非常基本的,如果您有一个复杂的对象(包含数组、嵌套对象等),您将需要以不同的方式处理它。
最后,我使用fetch
来调用我的 API。 如果您使用它,请务必不要设置Content-Type
标头,因为您将覆盖fetch
自动为您选择的标头,在大多数情况下这将是正确的标头。
fetch("localhost/api/test", {
method: 'POST',
headers: {
'Token': "dummy-token"
// DON'T overwrite Content-Type header
},
body: formData
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.