How create a MultipartFormFormatter for ASP.NET 4.5 Web API

前端 未结 2 956
野性不改
野性不改 2020-12-18 14:11

These links didn\'t help me:

  • Way 1
  • Way 2

Example:

//Model:
public class Group
{
    public int Id { get; set; }                 


        
相关标签:
2条回答
  • 2020-12-18 14:54
    public class MultipartFormFormatter : FormUrlEncodedMediaTypeFormatter
    {
        private const string StringMultipartMediaType = "multipart/form-data";
        private const string StringApplicationMediaType = "application/octet-stream";
    
        public MultipartFormFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue(StringMultipartMediaType));
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue(StringApplicationMediaType));
        }
    
        public override bool CanReadType(Type type)
        {
            return true;
        }
    
        public override bool CanWriteType(Type type)
        {
            return false;
        }
    
        public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var parts = await content.ReadAsMultipartAsync();
            var obj = Activator.CreateInstance(type);
            var propertiesFromObj = obj.GetType().GetRuntimeProperties().ToList();
    
            foreach (var property in propertiesFromObj.Where(x => x.PropertyType == typeof(FileModel)))
            {
                var file = parts.Contents.FirstOrDefault(x => x.Headers.ContentDisposition.Name.Contains(property.Name));
    
                if (file == null || file.Headers.ContentLength <= 0) continue;
    
                try
                {
                    var fileModel = new FileModel(file.Headers.ContentDisposition.FileName, Convert.ToInt32(file.Headers.ContentLength), ReadFully(file.ReadAsStreamAsync().Result));
                    property.SetValue(obj, fileModel);
                }
                catch (Exception e)
                {
                }
            }
    
            foreach (var property in propertiesFromObj.Where(x => x.PropertyType != typeof(FileModel)))
            {
                var formData = parts.Contents.FirstOrDefault(x => x.Headers.ContentDisposition.Name.Contains(property.Name));
    
                if (formData == null) continue;
    
                try
                {
                    var strValue = formData.ReadAsStringAsync().Result;
                    var valueType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
                    var value = Convert.ChangeType(strValue, valueType);
                    property.SetValue(obj, value);
                }
                catch (Exception e)
                {
                }
            }
    
            return obj;
        }
    
        private byte[] ReadFully(Stream input)
        {
            var buffer = new byte[16 * 1024];
            using (var ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
    }
    
    public class FileModel
    {
        public FileModel(string filename, int contentLength, byte[] content)
        {
            Filename = filename;
            ContentLength = contentLength;
            Content = content;
        }
    
        public string Filename { get; set; }
    
        public int ContentLength { get; set; }
    
        public byte[] Content { get; set; }
    
    }
    
    0 讨论(0)
  • 2020-12-18 15:09

    Please see below link for detail implementation: https://github.com/iLexDev/ASP.NET-WebApi-MultipartDataMediaFormatter

    Nuget: https://www.nuget.org/packages/MultipartDataMediaFormatter/

    I actually need to do "multipart/form-data" file upload and model binding today, I tried above lib from nuget and turns out it works as my expectation. Validation on model also works fine. Hopefully it helps to answer your question.

    0 讨论(0)
提交回复
热议问题