IFormFile 在 asp.net core 2.1 中总是返回 null
Posted
技术标签:
【中文标题】IFormFile 在 asp.net core 2.1 中总是返回 null【英文标题】:IFormFile always return null in asp.net core 2.1 【发布时间】:2019-03-21 02:45:51 【问题描述】:Api 方法如下所示
[HttpPost]
public async Task<BaseListResponse<MediaStorageModel>> MediaBrand(IFormFile file, int brandId)
var files = new List<IFormFile>();
files.Add(file);
var response = await this.Upload(files, "brand", brandId);
return response;
我的邮递员配置
将我的 dotnet 核心从 2.0 升级到 2.1 后无法正常工作,谁能帮忙解决这个问题。 怎么回事
【问题讨论】:
您的控制器是否使用[ApiController]
属性装饰?除其他外,该属性将默认绑定源从FromForm
切换到FromBody
,因此如果您需要实际接受multipart/form-data
或x-www-urleconded
请求主体,则需要将[FromForm]
添加到参数中。
即使将 FromForm 属性添加到模型参数时,我的 IFileInfo 仍然为空值,而我可以在 Request.Form.Files 列表中看到该文件...
它们都不适合我。我刚刚尝试了[FromForm(Name = "")] IFormFile file
属性,它对我有用。
【参考方案1】:
我找到了一种解决方法:
在控制器操作上使用
HttpPut
而不是HttPost
。
我也对这种行为感到惊讶。如果有人能解释为什么它解决了这个问题,那将对我有所帮助。
【讨论】:
【参考方案2】:更改您的方法参数以采用以下模型并添加 [FromForm],它应该可以工作。
public class FileUploadViewModel
public IFormFile File get; set;
public int BrandId get; set;
public async Task<BaseListResponse<MediaStorageModel>> MediaBrand([FromForm] FileUploadViewModel viewModel)
【讨论】:
【参考方案3】:我也遇到过同样的问题,我可以通过将“名称”命名参数应用到 FromForm 属性以及表单中文件字段的名称来解决它。它指定表单中的哪个字段绑定到方法参数。如下所示更改您的方法签名。
[HttpPost("status")]
public async Task<BaseListResponse<MediaStorageModel>> MediaBrand([FromForm(Name ="file")] IFormFile file, int brandId)
【讨论】:
【参考方案4】:下面的代码应该可以工作
[HttpPost]
public async Task<BaseListResponse<MediaStorageModel>> MediaBrand([FromQuery] int brandId, IFormFile file)
var files = new List<IFormFile>();
files.Add(file);
var response = await this.Upload(files, "brand", brandId);
return response;
【讨论】:
【参考方案5】:在您的表单中使用
enctype="multipart/form-data"
【讨论】:
宾果游戏。表单需要如下所示: 【参考方案6】:更新[FromForm]属性,不将参数放入Headers,将key的名称为file和brandId。
我测试过,没问题
【讨论】:
【参考方案7】:确保表单是正确的enctype
<form asp-action="Edit" enctype="multipart/form-data">
我还必须从生成的代码更改模型绑定的工作方式:
public async Task<IActionResult> Edit([Bind("Text,Example")] Example example)
到此代码:
public async Task<IActionResult> Edit(Example example)
【讨论】:
【参考方案8】:将 (Name = "body") 添加到对我有用的 from 表单
服务器调用:
[HttpPost]
[Route("UploadImage")]
public IActionResult UploadImage([FromForm(Name = "body")]IFormFile formData)
客户端代码:
let formData = new FormData();
formData.append('body', event.target.files[0]);
const config =
headers:
'content-type': 'multipart/form-data',
,
axios.post(ApiURL,formData, config);
【讨论】:
【参考方案9】:如果您使用 javascript 和 FormData 对象,您需要将每个文件的名称设置为“文件”
this.files.forEach((f) =>
formData.append("files", f, `$this.path/$f.name`);
);
如果您在帖子中使用其他名称,则需要在 post 方法的属性中设置它
formData.append("someName", f, `$this.path/$f.name`);
public async Task<IActionResult> Post([FromForm(Name ="someName")] List<IFormFile> files)
别忘了设置内容类型
'Content-Type': 'multipart/form-data'
【讨论】:
【参考方案10】:在我的例子中,我有一个使用自定义 HttpInterceptor 的 Angular 6 应用程序,它在发送到 api 之前将“application/json”的内容类型与令牌一起添加到每个 Http 请求中。
像下面的东西。删除带有“Content-Type”的行:application/json
。没有这个,这里的解决方案都不起作用。 .Net Core 现在可以更智能地翻译您发送到 api 的任何对象,到目前为止它与您为对象创建的模型相匹配。
import HttpEvent, HttpHandler, HttpInterceptor, HttpRequest from '@angular/common/http';
import Injectable from '@angular/core';
import Observable from 'rxjs/Observable';
@Injectable()
export class JwtHttpInterceptor implements HttpInterceptor
constructor()
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
const token = localStorage.getItem('token');
let clone: HttpRequest<any>;
if (token)
clone = request.clone(
setHeaders:
Accept: `application/json`,
'Content-Type': `application/json`,
Authorization: `Bearer $token`
);
【讨论】:
【参考方案11】:在我的情况下,它在网络核心中的工作方式如下
控制器:
[HttpPost]
public IActionResult ReadFormFile([FromForm]IFormFile miCsv)
请求正文:用作key与参数同名
Request Header: 用作Content-Type: multipart/form-data;边界=xxxxxxxxxxx 边界可以是任意值
【讨论】:
以上是关于IFormFile 在 asp.net core 2.1 中总是返回 null的主要内容,如果未能解决你的问题,请参考以下文章
IFormFile 始终为空(带有 MVC/Razor 的 ASP.NET Core)
使用 Asp.NET Core 3.1 框架将文件上传到服务器时如何使用 IFormFile 作为属性?
ASP.NET Core文件上传IFormFile于Request.Body的羁绊
ASP.NET Core文件上传IFormFile于Request.Body的羁绊