如何创建ASP.NET 4.5的Web API一个MultipartFormFormatter [英] How create a MultipartFormFormatter for ASP.NET 4.5 Web API

查看:157
本文介绍了如何创建ASP.NET 4.5的Web API一个MultipartFormFormatter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些链接没有帮助我:

例如:

  //型号:
公共类组
{
    公众诠释标识{搞定;组; }
    公共文件文件{搞定;组; }
}//控制器:
[HttpPost]
公共无效存储组([FromBody]组组){}//格式化:
公共类MultipartFormFormatter:MediaTypeFormatter
{
    私人常量字符串StringMultipartMediaType =的multipart / form-data的;    公共MultipartFormFormatter()
    {
        this.SupportedMediaTypes.Add(新MediaTypeHeaderValue(StringMultipartMediaType));    }    公众覆盖布尔CanReadType(类型类型)
    {
        返回true;
    }    公众覆盖布尔CanWriteType(类型类型)
    {
        返回false;
    }    公共异步替代任务<对象> ReadFromStreamAsync(类型类型,流readStream,HttpContent内容,IFormatterLogger formatterLogger)
    {
        //执行?要的是什么?
    }
}

应该采取什么方法 ReadFromStreamAsync 返回?

我怎么让它这样就可以正确地传递参数的动作?


解决方案

 公共类MultipartFormFormatter:FormUrlEn codedMediaTypeFormatter
{
    私人常量字符串StringMultipartMediaType =的multipart / form-data的;
    私人常量字符串StringApplicationMediaType =应用程序/八位字节流;    公共MultipartFormFormatter()
    {
        this.SupportedMediaTypes.Add(新MediaTypeHeaderValue(StringMultipartMediaType));
        this.SupportedMediaTypes.Add(新MediaTypeHeaderValue(StringApplicationMediaType));
    }    公众覆盖布尔CanReadType(类型类型)
    {
        返回true;
    }    公众覆盖布尔CanWriteType(类型类型)
    {
        返回false;
    }    公共覆盖异步任务<对象> ReadFromStreamAsync(类型类型,流readStream,HttpContent内容,IFormatterLogger formatterLogger)
    {
        VAR部分=等待content.ReadAsMultipartAsync();
        变种物镜= Activator.CreateInstance(类型);
        VAR propertiesFromObj = obj.GetType()GetRuntimeProperties()了ToList()。        的foreach(在propertiesFromObj.Where(X =&GT VAR财产; x.PropertyType == typeof运算(FileModel)))
        {
            var文件= parts.Contents.FirstOrDefault(X => x.Headers.ContentDisposition.Name.Contains(property.Name));            如果(文件== NULL || file.Headers.ContentLength< = 0)继续;            尝试
            {
                VAR fileModel =新FileModel(file.Headers.ContentDisposition.FileName,Convert.ToInt32(file.Headers.ContentLength)的readFully(file.ReadAsStreamAsync()的结果)。);
                property.SetValue(OBJ,fileModel);
            }
            赶上(例外五)
            {
            }
        }        的foreach(在propertiesFromObj.Where VAR财产(X =>!x.PropertyType = typeof运算(FileModel)))
        {
            VAR FORMDATA = parts.Contents.FirstOrDefault(X => x.Headers.ContentDisposition.Name.Contains(property.Name));            如果(FORMDATA == NULL)继续;            尝试
            {
                VAR strValue的= formData.ReadAsStringAsync()结果。
                VAR值类型= Nullable.GetUnderlyingType(property.PropertyType)? property.PropertyType;
                VAR值= Convert.ChangeType(strValue中,VALUETYPE);
                property.SetValue(OBJ,值);
            }
            赶上(例外五)
            {
            }
        }        返回OBJ;
    }    私人字节[]的readFully(流输入)
    {
        VAR缓冲=新的字节[16 * 1024];
        使用(VAR毫秒=新的MemoryStream())
        {
            INT读;
            而((读取= input.Read(缓冲液,0,buffer.Length))大于0)
            {
                ms.Write(缓冲,0,读);
            }
            返回ms.ToArray();
        }
    }
}公共类FileModel
{
    公共FileModel(字符串文件名,INT CONTENTLENGTH,字节[]的内容)
    {
        文件名=文件名;
        CONTENTLENGTH = CONTENTLENGTH;
        内容=的内容;
    }    公共字符串文件名{获得;组; }    公众诠释CONTENTLENGTH {搞定;组; }    公众的byte []内容{搞定;组; }}

These links didn't help me:

Example:

//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?
    }       
}

What should the method ReadFromStreamAsync return?

How do I make it so that you can properly transmit parameter to the action?

解决方案

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

}

这篇关于如何创建ASP.NET 4.5的Web API一个MultipartFormFormatter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆