测试用于文件上载的Web API,有一个像这样的简单视图模型:
public class TestModel { public string UserId {get;set;} public HttpPostedFileBase ImageFile {get;set;} }
用于方法:
[HttpPost] public void Create(TestModel model)
当我尝试将多部分/表单数据编码的表单发布到操作时,我收到此异常:
System.InvalidOperationException: No MediaTypeFormatter is available to read an object of type 'TestModel' from content with media type 'multipart/form-data'. at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content,Type type,IEnumerable`1 formatters,IFormatterLogger formatterLogger) at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content,IFormatterLogger formatterLogger) at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request,IFormatterLogger formatterLogger) at System.Web.Http.ModelBinding.FormatterParameterBinding.ExecuteBindingAsync(ModelMetadataProvider MetadataProvider,HttpActionContext actionContext,CancellationToken cancellationToken) at System.Web.Http.Controllers.HttpActionBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(HttpParameterBinding parameterBinder) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Threading.Tasks.TaskHelpers.IterateImpl(IEnumerator`1 enumerator,CancellationToken cancellationToken)
这适用于默认的MVC模型绑定器,但显然不适用于Web API.发现一些人提到你在上传文件时不能使用视图模型,只是将数据分成两个调用.这对我不起作用,因为我需要发布其他字段才能真正对上传的文件做些什么.有办法实现这个目标吗?
解决方法
看我原来的答案
https://stackoverflow.com/a/12603828/1171321
https://stackoverflow.com/a/12603828/1171321
基本上在我的博客文章和TryValidateProperty()建议中结合我的方法来维护模型验证注释.
编辑:
我继续在博客文章中对代码进行了代码增强.我将很快发布这个更新的代码.这是一个简单的示例,它验证每个属性并允许您访问结果数组.只是一种方法的样本
public class FileUpload<T> { private readonly string _RawValue; public T Value { get; set; } public string FileName { get; set; } public string MediaType { get; set; } public byte[] Buffer { get; set; } public List<ValidationResult> ValidationResults = new List<ValidationResult>(); public FileUpload(byte[] buffer,string mediaType,string fileName,string value) { Buffer = buffer; MediaType = mediaType; FileName = fileName.Replace("\"",""); _RawValue = value; Value = JsonConvert.DeserializeObject<T>(_RawValue); foreach (PropertyInfo Property in Value.GetType().GetProperties()) { var Results = new List<ValidationResult>(); Validator.TryValidateProperty(Property.GetValue(Value),new ValidationContext(Value) {MemberName = Property.Name},Results); ValidationResults.AddRange(Results); } } public void Save(string path,int userId) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var SafeFileName = Md5Hash.GetSaltedFileName(userId,FileName); var NewPath = Path.Combine(path,SafeFileName); if (File.Exists(NewPath)) { File.Delete(NewPath); } File.WriteAllBytes(NewPath,Buffer); var Property = Value.GetType().GetProperty("FileName"); Property.SetValue(Value,SafeFileName,null); } }