【发布时间】:2020-07-10 08:14:12
【问题描述】:
我在将文件上传到我的 Web Api 时遇到了一些问题。我创建了空的 Web API 项目并从some msdn page 尝试了这段代码:
public class UploadController : ApiController
{
[HttpPost]
[Route("api/upload/file")]
public async Task<HttpResponseMessage> PostFormData()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData fileData in provider.FileData)
{
Trace.WriteLine(fileData.Headers.ContentDisposition.FileName);//get FileName
Trace.WriteLine("Server file path: " + fileData.LocalFileName);//get File Path
}
return Request.CreateResponse(HttpStatusCode.OK, "pass upload file successed!");
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
但最初我需要从 react 应用发布此文件,我的代码如下所示:
const UploadFile = connect(
mapStateToProps,
mapDispatchToProps,
)(
class extends React.Component {
constructor(props) {
super(props);
this.state = {
file: '',
};
}
async submit(e) {
e.preventDefault();
const formData = new FormData();
formData.append('file', this.state.file, { type: 'text/csv' });
// I am dispatching redux action here, but to simplify tests with file upload I am using axios post right here
// i tried different urls with and without action names
post('http://localhost:44370/api/upload/file', formData)
.catch(error => {
console.log(error);
})
.then(() => {});
}
setFile(e) {
this.setState({ file: e.target.files[0] });
}
render() {
return (
<div className="container-fluid">
<form onSubmit={e => this.submit(e)}>
<div className="col-sm-12 btn btn-primary">
File Upload
</div>
<h1>File Upload</h1>
<input type="file" onChange={e => this.setFile(e)} />
<button className="btn btn-primary" type="submit">
Upload
</button>
</form>
</div>
);
}
},
);
但无论是从 react 应用程序还是邮递员,我都无法在我的操作上达到断点。我总是收到 404 not found via postman and ERR_CONNECTION_ABORTED from react app。
我也试过this solution和网上很多其他不同的方法,也试过使用HttpFileBase,但还是没有结果。
关于如何更改代码以便能够将文件上传到 Web Api 控制器的操作的任何想法?
PS。我能够使用这样的代码将文件上传到 asp.net 核心控制器:
[HttpPost]
public async Task<IActionResult> Post(IFormFile file)
{
if (file == null || file.Length == 0)
return Content("file not selected");
var fileId = Guid.NewGuid();
var path = Path.Combine(
Directory.GetCurrentDirectory(), "uploads",
file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
await file.CopyToAsync(stream);
}
和相同的反应代码,但我需要一个不是 .net 核心项目的解决方案,只是一个常规的 asp.net web api。
更新 根据评论,我尝试了只有表单的 html 页面:
<form
name="form1"
method="post"
enctype="multipart/form-data"
action="http://localhost:44370/api/upload/file"
>
<div>
<label for="file">File</label>
<input name="file" type="file" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
【问题讨论】:
-
我在我的环境中测试了控制器,它按预期工作。我可以通过简单地将带有
<input type="file" />和表单`enctype="multipart/form-data"` 和action="/api/upload/file"的HTML 页面添加到我的Web API 项目中来上传文件。所以你说反应代码正在工作,我说控制器代码正在工作。那么你一定是控制器配置或路由有问题。你把控制器类放在哪里了?我放在Controllers文件夹下 -
@OguzOzgul 是的,它在控制器文件夹下,我尝试了不同的路由配置,还添加了 [Route] 属性以确保我没有弄错。您的 html 页面只是普通的 html 还是来自 mvc 的 .cshtml 之类的东西?
-
@OguzOzgul 我再次尝试了html页面,但仍然是404,我用代码sn-p和屏幕截图更新了问题。
-
这是一个普通的 HTML 页面,非常基础,和你的完全一样,如果我的判断没有错的话,它帮助我们解决了问题。
标签: c# asp.net asp.net-web-api