我有一个包含许多属性的复杂类型,包括一个枚举。当将数据(application / x-www-form-urlencoded)输入到具有此类型作为参数的Web API方法时,它似乎允许为枚举属性的值传递任何字符串值。如果传递的值是枚举的其中一个成员,则它会正确分配值,但如果传递的值无效,则只会分配枚举的第一个成员。
描述问题的简单示例 - 给定模型类:
public enum EdibleFarmAnimal {
Sheep = 0,
Cow = 1,
Chicken = 2
}
public class ExampleModel {
public EdibleFarmAnimal EatThis { get; set; }
public string AnotherIrrelevantProperty { get; set; }
}
...以及网络API方法:
[HttpPut]
[ActionName("Put")]
public void Put(long id, ExampleModel model) {
// Do something with the model
}
如果我将EatThis=Cow&AnotherIrrelevantProperty=cheese
放到相关的URL上,它按预期工作,并且model.EatThis等于EdibleFarmAnimal.Cow,但是如果我PUT EatThis=Horse&AnotherIrrelevantProperty=cheese
则model.EatThis设置为EdibleFarmAnimal。绵羊,虽然我希望(并期望)某种错误被抛出,因为输入对于被反序列化的类型无效。
答案 0 :(得分:2)
Enum
默认值为0
,因此当它无法解析您的输入时,默认为0
,代表您枚举中的Sheep
(msdn article on this)。
您可以做的是创建Invalid
枚举元素并将其分配给0
:
public enum EdibleFarmAnimal {
Invalid = 0,
Sheep = 1,
Cow = 2,
Chicken = 3
}
然后检查您的输入是否有效。
答案 1 :(得分:1)
感谢Vsevolod的回答,我能够理解它为什么分配它的值,但是检测方案的解决方案是检查Web API方法中的ModelState.IsValid属性 - 这是设置的如果无法解析枚举值或日期时间,或者您添加到模型中的任何特定验证属性未通过给定输入,则为false。如this article:
中所述验证失败时,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
}
This answer描述了一种通过使用自定义属性来应用此类验证的好方法,作为检查每个API调用的替代方法。