如何在自定义媒体格式化程序中向Modelstate添加错误

时间:2013-07-25 12:39:12

标签: model-view-controller asp.net-web-api

我正在使用自定义媒体格式化程序来读取webapi中多部分的发布数据。处理自定义操作筛选器属性中的序列化错误和验证错误。在格式化程序中,我将输入映射到Type Object ImageMedia。我想将任何serliazation错误添加到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;}
}

1 个答案:

答案 0 :(得分: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");