Receive file and other form data together in ASP.NET Core Web API (boundary based request parsing)

前端 未结 7 683
悲&欢浪女
悲&欢浪女 2020-12-30 00:32

How would you form your parameters for the action method which is supposed to receive one file and one text value from the request?

I tried

相关标签:
7条回答
  • 2020-12-30 01:00

    I'm using the following code to accomplish this in order to parse a response from Mailgun, which comprises both files and text values.

    Please note that "dashifying" is just so property names like "MessageHeaders" get turned into "message-headers"; obviously you should use whatever logic makes sense for your use case.

    Controller:

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

    Model:

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-30 01:00

    You Can Get Multi Images By Sample Code Through MultiPart.

    First Inject IHttpContextAccessor To ConfigureService Method In Startup Class.Then Call It With Constructor Injection In Controller:

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

    Action Method Can Have Response Or Not.

            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
                }
    
    0 讨论(0)
  • 2020-12-30 01:02

    I had the similar issue and I solved the problem by using [FromForm] attribute and FileUploadModelView in the function as follow:

    [HttpPost]
    [Route("upload")]
    public async Task<IActionResult> Upload([FromForm] FileUploadViewModel model, [FromForm] string member_code)
    {
        var file = model.File;
        
        // ...
    }
    
    0 讨论(0)
  • 2020-12-30 01:03

    This is a quick solution for anyone who is facing the same issue:

    You will use ajax to send the following formData

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

    Then you will receive it in your controller like this:

    public string Post(IFormCollection data, IFormFile imageFile)
    

    Then you will access the data as you do normally:

    var name = data["name"];
    
    0 讨论(0)
  • 2020-12-30 01:10

    I guess you're transmitting the file and text in proper JSON format.

    You should create a new class which includes file and text as properties of type string. Add the new class to your method arguments with attribute[FromBody] and you'll be able to parse the image string according to your needs.

    Another way would be accessing the whole request content via

    await Request.Content.ReadAsStringAsync();
    

    You would then have to parse the entire content, though.

    0 讨论(0)
  • 2020-12-30 01:18

    This page helped me a lot https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads

    so now in my code I have the controller method as:

     public async Task<IActionResult> UploadFiles(UploadedFile ups)
    

    and a class for the model as

    public class UploadedFile
        {
            public string UploadName { get; set; }
            public List<IFormFile> Files { get; set; }
        }
    

    and the form like

    <form method="post" enctype="multipart/form-data" asp-controller="Files" asp-action="UploadFiles">
    
    0 讨论(0)
提交回复
热议问题