在 ASP.NET Core Web API 中一起接收文件和其他表单数据(基于边界的请求解析)
Posted
技术标签:
【中文标题】在 ASP.NET Core Web API 中一起接收文件和其他表单数据(基于边界的请求解析)【英文标题】:Receive file and other form data together in ASP.NET Core Web API (boundary based request parsing) 【发布时间】:2017-03-30 12:32:18 【问题描述】:对于应该从请求中接收一个file
和一个text
值的操作方法,您将如何形成参数?
我试过了
public string Post([FromBody]string name, [FromBody]IFormFile imageFile)
并尝试从邮递员那里击中它,但它给了我500 Internal Server Error
。我也无法调试它,因为它永远不会命中我放置断点的操作方法中的第一条语句。
知道如何解析基于边界的请求并提取文件和其他文本字段吗?我是 ASP.NET Core 的新手。
【问题讨论】:
这个问题有什么解决办法吗? @MadurikaWelivita 我为表单数据和图像开发了单独的 API,但您应该尝试用户发布的答案。 【参考方案1】:我遇到了类似的问题,我通过在函数中使用[FromForm]
属性和FileUploadModelView
解决了这个问题,如下所示:
[HttpPost]
[Route("upload")]
public async Task<IActionResult> Upload([FromForm] FileUploadViewModel model, [FromForm] string member_code)
var file = model.File;
// ...
【讨论】:
FileUploadViewModel
到底是什么?【参考方案2】:
对于遇到相同问题的任何人来说,这是一个快速的解决方案:
你将使用ajax发送如下formData
let formData: FormData;
formData = new FormData();
formData.append('imageFile', imageFile);
formData.append('name', name);
然后你会像这样在你的控制器中收到它:
public string Post(IFormCollection data, IFormFile imageFile)
然后您将像往常一样访问数据:
var name = data["name"];
【讨论】:
我在 ASP.NET Core 端努力检索 FormData 值,最后一行帮助了我。谢谢。【参考方案3】:在 HomeController.cs 中
using Microsoft.AspNetCore.Hosting;
.......
private IHostingEnvironment _environment;
public HomeController(IHostingEnvironment environment)
_environment = environment;
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(IFormCollection formdata)
var files = HttpContext.Request.Form.Files;
foreach (var file in files)
var uploads = Path.Combine(_environment.WebRootPath, "Images");
if (file.Length > 0)
string FileName = Guid.NewGuid(); // Give file name
using (var fileStream = new FileStream(Path.Combine(uploads, FileName), FileMode.Create))
file.CopyToAsync(fileStream);
在视图中 - Index.cshtml
<form method="post" enctype="multipart/form-data" >
.....
</form>
你可以试试这个代码。
谢谢!!
【讨论】:
看来您将IFormCollection
作为控制器方法的参数,然后完全忽略它并从HttpContext.Request
中重新提取它。这样做是有原因的,还是只是疏忽? :)【参考方案4】:
我使用以下代码来完成此操作,以解析包含文件和文本值的a response from Mailgun。
请注意,“dashifying”只是为了让像“MessageHeaders”这样的属性名称变成“message-headers”;显然,您应该使用对您的用例有意义的任何逻辑。
控制器:
using System;
using Microsoft.AspNetCore.Mvc;
using NuGet.Protocol.Core.v3;
namespace Potato
[Route("api/[controller]")]
public class MailgunController : Controller
[HttpPost]
public IActionResult Post()
MailgunEmail email = new MailgunEmail(Request);
return Ok(email.ToJson());
型号:
using System;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
namespace Potato
public class MailgunEmail
public IEnumerable<IFormFile> Attachments get; set;
public string Recipient get; set;
public string Sender get; set;
public string From get; set;
public string Subject get; set;
public string BodyPlain get; set;
public string StrippedText get; set;
public string StrippedSignature get; set;
public string BodyHtml get; set;
public string StrippedHtml get; set;
public int? AttachmentCount get; set;
public int Timestamp get; set;
public string Token get; set;
public string Signature get; set;
public string MessageHeaders get; set;
public string ContentIdMap get; set;
public MailgunEmail(HttpRequest request)
var form = request.Form;
Attachments = new List<IFormFile>(form.Files);
foreach (var prop in typeof(MailgunEmail).GetProperties())
string propName = Dashify(prop.Name);
var curVal = form[propName];
if (curVal.Count > 0)
prop.SetValue(this, To(curVal[0], prop.PropertyType), null);
private object To(IConvertible obj, Type t)
Type u = Nullable.GetUnderlyingType(t);
if (u != null)
return (obj == null) ? GetDefaultValue(t) : Convert.ChangeType(obj, u);
else
return Convert.ChangeType(obj, t);
private object GetDefaultValue(Type t)
if (t.GetTypeInfo().IsValueType)
return Activator.CreateInstance(t);
return null;
private string Dashify(string source)
string result = "";
var chars = source.ToCharArray();
for (int i = 0; i < chars.Length; ++i)
var c = chars[i];
if (i > 0 && char.IsUpper(c))
result += '-';
result += char.ToLower(c);
return result;
【讨论】:
【参考方案5】:这个页面帮了我很多https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads
所以现在在我的代码中,我的控制器方法为:
public async Task<IActionResult> UploadFiles(UploadedFile ups)
以及模型的类
public class UploadedFile
public string UploadName get; set;
public List<IFormFile> Files get; set;
和像
这样的形式<form method="post" enctype="multipart/form-data" asp-controller="Files" asp-action="UploadFiles">
【讨论】:
感谢@mslliviu,如果它对我有用,我会尝试更新 它不适用于使用邮递员的 asp.net core 2 操作。所有非文件属性都已填充,文件属性为空。请求对象包含文件。【参考方案6】:我想发送一个复杂的对象而不是一个文本值。也可以像下面那样做。
发送表单数据:
let data = new FormData();
data.append("file", file, file.name);
data.append("someData", JSON.stringify(someData));
在控制器中使用表单数据:
public async Task<IActionResult> OnPostUploadAsync( IFormCollection data )
var files = data.Files;
if (data.TryGetValue("someData", out var someData))
//use files & some data (json string)
【讨论】:
【参考方案7】:您可以通过MultiPart通过示例代码获取多张图片。
首先注入IHttpContextAccessor到ConfigureService方法中 启动类。然后用 Constructor Injection 调用它 控制器:
private readonly IHttpContextAccessor _httpContextAccessor;
public FileController(IHttpContextAccessor httpContextAccessor)
_httpContextAccessor = httpContextAccessor;
Action 方法可以有响应也可以不响应。
public async Task<object> UploadImage()
var fileBytes = new List<byte[]>();
var files =
_httpContextAccessor.HttpContext.Request.Form.Files;
foreach (var file in files)
if (file.Length > 0)
using (var memoryStream = new MemoryStream())
await file.CopyToAsync(memoryStream);
fileBytes.Add(memoryStream.ToArray());
// TODO: Write Code For Save Or Send Result To Another Services For Save
【讨论】:
【参考方案8】:我猜你正在以正确的 JSON 格式传输文件和文本。
您应该创建一个包含文件和文本作为字符串类型属性的新类。使用 attribute[FromBody] 将新类添加到您的方法参数中,您将能够根据需要解析图像字符串。
另一种方法是通过
访问整个请求内容await Request.Content.ReadAsStringAsync();
不过,您将不得不解析整个内容。
【讨论】:
我在Request
对象中没有 Content
属性。另外,我没有在 JSON 中传输文件和文本。我想知道这是否可能很容易。我正在发送multipart/form-data
(基于边界的请求)。抱歉,您的解决方案对我不起作用。以上是关于在 ASP.NET Core Web API 中一起接收文件和其他表单数据(基于边界的请求解析)的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web API 在 API GET 请求中检索空白记录
使用 ASP.NET Core MVC 创建 Web API