Web API - 将编码的输入表单设置为复杂类型的枚举允许无效值
本文关键字:许无效 枚举 无效 类型 API 编码 输入 Web 设置 表单 复杂 | 更新日期: 2023-09-27 18:34:20
>我有一个具有许多属性的复杂类型,包括一个枚举。当将数据(application/x-www-form-urlencoded)PUTing到具有此类型作为参数的Web API方法时,它似乎允许为枚举属性的值传递任何字符串值。如果传递的值是枚举的成员之一,则它正确分配值,但如果传递了无效值,则它只是分配枚举的第一个成员。
描述问题的简单示例 - 给定模型类:
public enum EdibleFarmAnimal {
Sheep = 0,
Cow = 1,
Chicken = 2
}
public class ExampleModel {
public EdibleFarmAnimal EatThis { get; set; }
public string AnotherIrrelevantProperty { get; set; }
}
。和 Web API 方法:
[HttpPut]
[ActionName("Put")]
public void Put(long id, ExampleModel model) {
// Do something with the model
}
如果我将EatThis=Cow&AnotherIrrelevantProperty=cheese
放入相关 URL,它会按预期和模型工作。EatThis等于EdibleFarmAnimal.Cow,但是如果我EatThis=Horse&AnotherIrrelevantProperty=cheese
那么模型。EatThis 设置为 EdibleFarmAnimal.Sheep,而我希望(并期望)抛出某种错误,因为输入对于它被反序列化的类型无效。
C# 中的Enum
的默认值为 0
,因此当它无法解析您的输入时,它默认为 0
,代表枚举中的Sheep
(MSDN 文章)。
您可以做的是创建一个Invalid
枚举元素并将其分配给0
:
public enum EdibleFarmAnimal {
Invalid = 0,
Sheep = 1,
Cow = 2,
Chicken = 3
}
然后检查您的输入是否有效。
多亏了 Vsevolod 的回答,我能够理解它为什么要分配它的值,但是检测场景的解决方案是检查 Web API 方法中的 ModelState.IsValid 属性 - 如果无法分析枚举值或日期时间,或者您添加到模型的任何特定验证属性未针对给定输入传递,则此属性设置为 false。如本文所述:
验证失败时,Web API 不会自动向客户端返回错误。由控制器操作来检查模型状态并做出适当的响应。
因此,要更正原始示例,使其现在引发适当的错误:
[HttpPut]
[ActionName("Put")]
public void Put(long id, ExampleModel model) {
if (!ModelState.IsValid) throw new HttpResponseException(HttpStatusCode.BadRequest);
// Do something with the model
}
此答案描述了一种通过使用自定义属性来应用此类验证的好方法,作为检查每个 API 调用的替代方法。