首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Asp.Net Core文件上传的文件总是空的

使用Asp.Net Core文件上传的文件总是空的
EN

Stack Overflow用户
提问于 2017-05-21 13:43:06
回答 4查看 21.3K关注 0票数 7

我正在使用ASP.NET核心Web实现文件上传,使用Range2来处理请求。

我的html代码看起来如下:

代码语言:javascript
复制
<input #fileInput type="file"/>
<button (click)="addFile()">Add</button>

和angular2代码

代码语言:javascript
复制
addFile(): void {
    let fi = this.fileInput.nativeElement;
    if (fi.files && fi.files[0]) {
        let fileToUpload = fi.files[0];
        this.documentService
            .uploadFile(fileToUpload)
            .subscribe(res => {
                console.log(res);
        });
    }
}

服务看上去就像

代码语言:javascript
复制
public uploadFile(file: any): Observable<any> {
    let input = new FormData();
    input.append("file", file, file.name);
    let headers = new Headers();
    headers.append('Content-Type', 'multipart/form-data');
    let options = new RequestOptions({ headers: headers });
    return this.http.post(`/api/document/Upload`, input, options);
}

和控制器代码

代码语言:javascript
复制
[HttpPost]
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 this.UploadFile(file.ContentDisposition);
        }
    }
}

我的RequestHeader看起来就像

代码语言:javascript
复制
POST /shell/api/document/Upload HTTP/1.1
Host: localhost:10050
Connection: keep-alive
Content-Length: 2
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJDb3JyZWxhdGlvbklkIjoiZDZlNzE0OTUtZTM2MS00YTkxLWExNWUtNTc5ODY5NjhjNDkxIiwiVXNlcklkIjoiMSIsIlVzZXJOYW1lIjoiWjk5OTkiLCJXb3Jrc3BhY2UiOiJRc3lzVFRAU09BVEVNUCIsIk1hbmRhbnRJZCI6IjUwMDEiLCJDb3N0Q2VudGVySWQiOiIxMDAxIiwiTGFuZ3VhZ2VDb2RlIjoiMSIsIkxhbmd1YWdlU3RyaW5nIjoiZGUtREUiLCJTdGF0aW9uSWQiOiI1NTAwMSIsIk5hbWUiOiJJQlMtU0VSVklDRSIsImlzcyI6InNlbGYiLCJhdWQiOiJodHRwOi8vd3d3LmV4YW1wbGUuY29tIiwiZXhwIjoxNDk1Mzc4Nzg4LCJuYmYiOjE0OTUzNzUxODh9.5ZP7YkEJ2GcWX9ce-kLaWJ79P4d2iCgePKLqMaCe-4A
Origin: http://localhost:10050
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Content-Type: multipart/form-data
Accept: application/json, text/plain, */*
Referer: http://localhost:10050/fmea/1064001/content
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

我面临的问题是,该文件在控制器中始终为空。

请有人帮我解决这个问题。

提前谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-05-22 11:07:31

您不需要在FormData中使用“多部分/表单数据”

在角2分量中:

代码语言:javascript
复制
<input type="file" class="form-control" name="documents" (change)="onFileChange($event)" />

onFileChange(event: any) {
    let fi = event.srcElement;
    if (fi.files && fi.files[0]) {
        let fileToUpload = fi.files[0];

        let formData:FormData = new FormData();
         formData.append(fileToUpload.name, fileToUpload);

        let headers = new Headers();
        headers.append('Accept', 'application/json');
        // DON'T SET THE Content-Type to multipart/form-data, You'll get the Missing content-type boundary error
        let options = new RequestOptions({ headers: headers });

        this.http.post(this.baseUrl + "upload/", formData, options)
                 .subscribe(r => console.log(r));
    }
}

在API方面

代码语言:javascript
复制
[HttpPost("upload")]
public async Task<IActionResult> Upload()
{
    var files = Request.Form.Files;

    foreach (var file in files)
    {
       // to do save
    }

    return Ok();
}
票数 20
EN

Stack Overflow用户

发布于 2018-08-25 13:09:07

更新:经过ASP.NET核心团队的一些澄清,它与Startup类中的compat开关有关。如果你这样设置的话:

代码语言:javascript
复制
services
    .AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

如果还从文件参数中删除[FromForm]属性,那么您就可以了。

“老邮报”:我在最新的ASP.NET Core WebApi中遇到了类似的问题(在本文发表时为2.1.2),这个问题只有在经历了一个小时的堆积如山、研究和大量的尝试和错误之后才能意外地解决。我发布的文件来自一个像这样的Range6应用程序:

代码语言:javascript
复制
const formData: FormData = new FormData();
formData.append('file', file, file.name);

const req = new HttpRequest('POST', 'upload-url', formData, {
    reportProgress: true
});

this.http.request(req).subscribe(...) // omitted the rest

问题是,即使将IFormFile file摆在前面,[FromForm]操作方法参数也始终是null[FromForm]是必需的,因为ASP.NET Core2.1中的api控制器行为发生了变化,其中[FromBody]成为了[FromBody]控制器的默认设置。奇怪的是,它仍然不起作用,它的价值保持了null

最后,我通过使用属性显式声明表单内容参数的名称来解决这个问题,如下所示:

代码语言:javascript
复制
public async Task<IActionResult> UploadLogo([FromForm(Name = "file")] IFormFile file)        
{
     ...
}

现在,文件上传被正确绑定到控制器参数。我希望这能对将来的人有所帮助,因为这几乎使我失去了理智。

票数 6
EN

Stack Overflow用户

发布于 2017-11-24 18:56:49

另一种使用dotnet核心的方法是使用IFormFile接口,并设置默认标题:

角2

代码语言:javascript
复制
 let formData = new FormData();
 formData.append("file", yourUploadFile);

 this.http.post("your_api_path", formData).subscribe(r => console.log(r));

Dotnet核心

代码语言:javascript
复制
 [HttpPost]
 [Route("/your_api_path")]
 public async Task<IActionResult> Upload(IFormFile file) {
     //...next awaiters...    
}

如果要发送多个文件,可以使用ICollection<IFormFile>作为上载参数。

对于发送多个属性,可以使用自定义模型对象,IFormFile将是属性之一。

希望能帮上忙!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44097604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档