我是react.js和ASP.Net核心2.0的新手。现在使用ASP.Net core 2.0作为后端API和react.js作为应用程序接口(前端)编写项目。我想知道如何上传文件。我尝试了如下,但在后端方面,参数值(IFromFile文件)始终为null。而且似乎文件没有正确发布。这是我的代码:
.Net core(API)
[HttpPost]
[Route("upload")]
public async Task Upload(IFormFile file)
{
if (file == null) throw new Exception("File is null");
if (file.Length == 0) throw new Exception("File is empty");
using (Stream stream = file.OpenReadStream())
{
using (var binaryReader = new BinaryReader(stream))
{
var fileContent = binaryReader.ReadBytes((int)file.Length);
// await _uploadService.AddFile(fileContent, file.FileName, file.ContentType);
}
}
}
React.js
handleClick(event){
event.preventDefault();
// console.log("handleClick",event);
var self = this;
var apiBaseUrl = axios.defaults.baseURL + "user/upload";
if(this.state.filesToBeSent.length>0){
var filesArray = this.state.filesToBeSent;
const reader = new FileReader();
for(var i in filesArray){
//console.log("files",filesArray[i][0]);
var file = filesArray[i][0];
axios.post(apiBaseUrl, {data: file});
}
alert("File upload completed");
}
else{
alert("Please select files first");
}
}
请告知我该如何解决这个问题。
答案 0 :(得分:6)
我完成了以下工作:
at .Net core 2.0 web api
使用Microsoft.AspNetCore.Http;
我创建了一个模型类
namespace Marter_MRM.Models
{
public class FileUploadViewModel
{
public IFormFile File { get; set; }
public string source { get; set; }
public long Size { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string Extension { get; set; }
}
}
然后我创建了一个控制器类并编写了如下函数。
[HttpPost]
[Route("upload")]
public async Task<IActionResult> Upload(FileUploadViewModel model) {
var file = model.File;
if (file.Length > 0) {
string path = Path.Combine(_env.WebRootPath, "uploadFiles");
using (var fs = new FileStream(Path.Combine(path, file.FileName), FileMode.Create))
{
await file.CopyToAsync(fs);
}
model.source = $"/uploadFiles{file.FileName}";
model.Extension = Path.GetExtension(file.FileName).Substring(1);
}
return BadRequest();
}
编写api调用函数如下:
handleUploadClick(event){
event.preventDefault();
var self = this;
var apiBaseUrl = axios.defaults.baseURL + "user/upload";
if(this.state.filesToBeSent.length>0){
var filesArray = this.state.filesToBeSent;
let f = new FormData();
for(var i in filesArray){
//console.log("files",filesArray[i][0]);
f = new FormData();
f.append("File",filesArray[i][0] )
axios.post(apiBaseUrl, f, {
headers: {'Content-Type': 'multipart/form-data'}
});
}
alert("File upload completed");
}
else{
alert("Please select files first");
}
}
它完美无缺。谢谢!
答案 1 :(得分:3)
这个答案是正确的,但是我在将图像保存到API中时遇到了问题,因此我按您所见的那样更改了方法,然后运行良好。您应该在API方法中将参数设置为[FromForm]
public async Task<IActionResult> Upload([FromForm]FileUploadViewModel model){...}
答案 2 :(得分:1)
就我而言,我只是错过了在表单中添加 multipart / form-data 。
如果您的控制器正在使用 IFormFile 接受上载的文件,但您发现该值始终为空,请确认您的HTML表单指定的 enctype 值为 multipart / form-data 。如果未在 元素上设置此属性,则不会进行文件上载,并且任何绑定的 IFormFile 参数将为空。
示例:-
<form method="post" enctype="multipart/form-data" asp-controller="UploadFiles" asp-action="Index">
<div class="form-group">
<div class="col-md-10">
<p>Upload one or more files using this form:</p>
<input type="file" name="files" multiple />
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="Upload" />
</div>
</div>
</form>
删除此输入元素上的 multiple 属性,以仅允许上传单个文件。
答案 3 :(得分:0)
[Route("api/[controller]")]
[ApiController]
public class UploaderController : ControllerBase
{
[HttpPost]
public dynamic UploadJustFile(IFormCollection form)
{
try
{
foreach (var file in form.Files)
{
string path = Path.Combine(@"C:\uploadFiles");
using (var fs = new FileStream(Path.Combine(path, file.FileName), FileMode.Create))
{
file.CopyToAsync(fs);
}
UploadFile(file);
}
return new { Success = true };
}
catch (Exception ex)
{
return new { Success = false, ex.Message };
}
}
并在用户界面中使用此
uploadJustFile(e) {
e.preventDefault();
let state = this.state;
this.setState({
...state,
justFileServiceResponse: 'Please wait'
});
if (!state.hasOwnProperty('files')) {
this.setState({
...state,
justFileServiceResponse: 'First select a file!'
});
return;
}
let form = new FormData();
for (var index = 0; index < state.files.length; index++) {
var element = state.files[index];
form.append('file', element);
}
debugger;
axios.post('/api/uploader', form)
.then((result) => {
let message = "Success!"
if (!result.data.success) {
message = result.data.message;
}
this.setState({
...state,
justFileServiceResponse: message
});
})
.catch((ex) => {
console.error(ex);
});
}