在ASP.NET Core Web API中接收文件和其他表单数据(基于边界的请求解析)

时间:2016-11-16 10:37:51

标签: c# asp.net asp.net-core .net-core

您如何为应该从请求中收到一个file和一个text值的操作方法形成参数?

我试过这个

public string Post([FromBody]string name, [FromBody]IFormFile imageFile)

尝试从Postman打它,但它给了我500 Internal Server Error。我也无法调试它,因为它永远不会触及我放置断点的action方法中的第一个语句。

任何想法我们如何解析基于边界的请求并提取文件和其他文本字段?我是ASP.NET Core的新手。

8 个答案:

答案 0 :(得分:13)

我有类似的问题,我通过在函数中使用[FromForm]属性和FileUploadModelView来解决问题,如下所示:

[HttpPost]
        [Route("upload")]
        public async Task<IActionResult> Upload([FromForm] FileUploadViewModel model, [FromForm] string member_code)
        {
            var file = model.File;

            ...
        }

答案 1 :(得分:8)

对于面临相同问题的任何人,这都是一种快速的解决方案:

您将使用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"];

答案 2 :(得分:4)

我使用以下代码来完成此操作,以便解析包含文件和文本值的a response from Mailgun

请注意&#34;表示&#34;就像#34; MessageHeaders&#34;转入&#34; message-headers&#34 ;;显然你应该使用任何对你的用例有意义的逻辑。

控制器:

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;
        }
    }
}

答案 3 :(得分:1)

这页帮助了我很多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">

答案 4 :(得分:1)

在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>

您可以尝试使用此代码。

谢谢!

答案 5 :(得分:1)

我想发送一个复杂的对象而不是文本值。也可以像下面那样做。

发送表单数据:

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)
  }
}

答案 6 :(得分:0)

您可以通过MultiPart通过示例代码获取多张图像。

首先注入 IHttpContextAccessor 以在其中配置Service方法 启动类。然后使用构造函数注入在 控制器:

        private readonly IHttpContextAccessor _httpContextAccessor;

          public FileController(IHttpContextAccessor httpContextAccessor)
                {
                    _httpContextAccessor = httpContextAccessor;           
                }

动作方法可以有反应。

        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
            }

答案 7 :(得分:-1)

我猜你正在以适当的JSON格式传输文件和文本。

您应该创建一个新类,其中包含文件和文本作为string类型的属性。使用属性[FromBody]将新类添加到方法参数中,您将能够根据需要解析图像字符串。

另一种方法是通过

访问整个请求内容
await Request.Content.ReadAsStringAsync();

然而,您必须解析整个内容。