加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 如何为ASP.NET 4.5 Web API创建MultipartFormFor

发布时间:2020-12-15 23:55:12 所属栏目:asp.Net 来源:网络整理
导读:这些链接对我没有帮助: Way 1 Way 2 例: //Model:public class Group{ public int Id { get; set; } public File File { get; set; }}//Controller:[HttpPost]public void SaveGroup([FromBody]Group group) {}//Formatter:public class MultipartFormForm
这些链接对我没有帮助:

> Way 1
> Way 2

例:

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

//Controller:
[HttpPost]
public void SaveGroup([FromBody]Group group) {}

//Formatter:
public class MultipartFormFormatter : MediaTypeFormatter
{
    private const string StringMultipartMediaType = "multipart/form-data";

    public MultipartFormFormatter()
    {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue(StringMultipartMediaType));

    }

    public override bool CanReadType(Type type)
    {
        return true;
    }

    public override bool CanWriteType(Type type)
    {
        return false;
    }

    public async override Task<object> ReadFromStreamAsync(Type type,Stream readStream,HttpContent content,IFormatterLogger formatterLogger)
    {
        //Implementation? What here should be?
    }       
}

ReadFromStreamAsync方法应该返回什么?

如何使它能够正确地将参数传递给动作?

解决方法

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,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,buffer.Length)) > 0)
            {
                ms.Write(buffer,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; }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读