0

我正在使用自定义媒体格式化程序来读取 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;}
}
4

1 回答 1

1

您可以将错误添加到IFormatterLogger传递给ReadFromStreamAsync方法的提供的上下文中:

public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent request,
   IFormatterLogger formatterContext)

例子:

formatterLogger.LogError(errorPath: "OrderedDate", errorMessage: "Not a valid date");
于 2013-07-25T14:52:19.197 回答