验证Web api 2对象参数中的枚举

时间:2017-02-17 15:30:38

标签: c# validation asp.net-web-api asp.net-web-api2

假设您将一个类实例发送到控制器,并且该类具有Enum类型的属性。

public class CoffeeController : ApiController
{
    [HttpPost]
    public async Task<IHttpActionResult> OrderAsync(Order request)
    {
        return Ok();
    }
}

public enum CoffeeType
{
    Latte,
    Mocha,
    Espresso
}

public class Order
{
    public CoffeeType Type { get; set; }
    public string Name { get; set; }
}

如果请求中的枚举成员名称中存在错误,则应用程序不会抛出异常。它使用默认的枚举值代替:

{"name":"Dan", 'type':"ocha"}=>{"Name":"Dan", "Type":"Latte"}

这对我来说似乎很奇怪。 为什么要使用这种行为?

有抛出错误的优雅方法吗?

3 个答案:

答案 0 :(得分:1)

这样做是因为Enums基于整数类型,所以它们总是有一个值(值类型不能为null),默认为0.使用以下解决方法

public enum CoffeeType
{
    Invalid = 0
    Latte = 1,
    Mocha = 2,
    Espresso = 3
}

答案 1 :(得分:1)

将验证应用于您的模型。创建一个ActionFilterAttribute并将其连接到您的管道或使用它装饰您的端点。建议您将FluentValidation视为一个很好的库来执行验证。

请参阅this article中的ValidateModelStateFilter示例,以获取一个很好的示例。

答案 2 :(得分:0)

正如Brett所写,你可以使用ModelState.IsValid和ModelState会有错误。 如果您只需要抛出错误,可以使用自定义媒体格式化程序,例如:

public class OrderJsonFormatter : BufferedMediaTypeFormatter
    {
        public OrderJsonFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        }

        public override bool CanReadType(Type type)
        {
            var canRead = type == typeof(Order);
            return canRead;
        }

        public override bool CanWriteType(Type type)
        {
            return false;
        }

        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return this.ReadFromStream(type, readStream, content, formatterLogger, CancellationToken.None);
        }

        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
        {
            using (var reader = new StreamReader(readStream))
            {
                using (var jsonReader = new JsonTextReader(reader))
                {
                    var jsonSerializer = new JsonSerializer();

                    if (type == typeof(Order))
                    {


                        try
                        {
                            var entity = jsonSerializer.Deserialize<Order>(jsonReader);
                            return entity;
                        }
                        catch (Exception ex)
                        {
                         //log error here
                            throw;
                        }
                    }

                    return null;
                }
            }
        }


    }

并注册:

 GlobalConfiguration.Configuration.Formatters.Insert(0, new OrderJsonFormatter());