假设您将一个类实例发送到控制器,并且该类具有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"}
这对我来说似乎很奇怪。 为什么要使用这种行为?
有抛出错误的优雅方法吗?
答案 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());