如何创建ASP.NET 4.5的Web API一个MultipartFormFormatter [英] How create a MultipartFormFormatter for ASP.NET 4.5 Web API
本文介绍了如何创建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屋!
查看全文