我正在使用自定义媒体格式化程序来读取 webapi 中多部分的发布数据。处理自定义操作过滤器属性中的序列化错误和验证错误。在格式化程序中,我将输入映射到类型对象 ImageMedia。我想将任何序列化错误添加到 ModelState 中,以便我可以处理 CustomFilterAttribute 中的错误,这些错误会收到 ActionContext。这是代码:
public class ImageMediaFormatter : MediaTypeFormatter
{
public ImageMediaFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpeg"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpg"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/png"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/gif"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
}
public override bool CanReadType(Type type)
{
return type == typeof(ImageMedia);
}
public override bool CanWriteType(Type type)
{
return false;
}
public override Task<object> ReadFromStreamAsync(
Type type, Stream stream, HttpContent request,
IFormatterLogger formatterContext)
{
return Task.Factory.StartNew<object>(() =>
{
var streamProvider = new MultipartMemoryStreamProvider();
var keys = new Dictionary<string, string>();
var result = request.ReadAsMultipartAsync(streamProvider).Result;
//get and remove random slashes from posted vaues
var categoryid =
streamProvider.Contents.First(x => x.Headers.ContentDisposition.Name.Contains("userGeneratedCategoryId")).ReadAsStringAsync().Result.Replace("\"", string.Empty);
keys.Add(Constants.UserGeneratedCategoryId, categoryid);
var imageBuffer =
streamProvider.Contents.First(x => x.Headers.ContentDisposition.Name.Contains(Constants.ImageFile)).ReadAsByteArrayAsync().Result;
return new ImageMedia(keys, imageBuffer);
});
}
}
public class ImageMedia
{
public ImageMedia(Dictionary<string, string> keys, byte[] imageBuffer)
: this()
{
var keyvaluePair = new KeyValuePair<string, string>();
foreach (var property in GetType().GetProperties())
{
try
{
keyvaluePair = keys.FirstOrDefault(pair => pair.Key.ToLower() == property.Name.ToLower());
if (!string.IsNullOrEmpty(keyvaluePair.Key))
{
property.SetValue(this, keyValuePair.Value, null);
}
}
catch (Exception ex)
{
// Add these serialization errors to the Model State so I can handle these in a Custom Validation Action Attribute
Errors.Add(keyvaluePair.Key, new List<string> { ex.Message });
IsValid = false;
}
}
Buffer = imageBuffer;
}
private ImageMedia()
{
Errors = new Dictionary<string, List<string>>();
}
public int UserGeneratedCategoryId { get; set; }
public byte[] Buffer { get;set;}
}