C# Web API-复杂类型上枚举的表单编码输入允许无效值
我有一个具有许多属性的复杂类型,包括一个枚举。将数据(application/x-www-form-urlencoded)放入具有此类型作为参数的web API方法时,它似乎允许为枚举属性的值传递任何字符串值。如果传递的值是枚举的一个成员,则会正确分配该值,但如果传递的值无效,则只分配枚举的第一个成员 描述问题的简单示例-给定模型类:C# Web API-复杂类型上枚举的表单编码输入允许无效值,c#,asp.net-web-api,enums,C#,Asp.net Web Api,Enums,我有一个具有许多属性的复杂类型,包括一个枚举。将数据(application/x-www-form-urlencoded)放入具有此类型作为参数的web API方法时,它似乎允许为枚举属性的值传递任何字符串值。如果传递的值是枚举的一个成员,则会正确分配该值,但如果传递的值无效,则只分配枚举的第一个成员 描述问题的简单示例-给定模型类: public enum EdibleFarmAnimal { Sheep = 0, Cow = 1, Chicken = 2 } public
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
}
如果我将eathis=Cow&anotherrelevantproperty=cheese
放在相关URL中,它会按预期工作,model.eathis等于EdibleFarmAnimal.Cow,但是如果我将eathis=Horse&anotherrelevantproperty=cheese
放在model.eathis中,则会设置为EdibleFarmAnimal.Sheep,而我希望(并期望)要抛出某种类型的错误,因为输入对其反序列化到的类型无效。Enum
在C#中有一个默认值0
,因此当它无法解析您的输入时,它默认为0
,它在您的Enum()中代表Sheep
您可以做的是创建一个无效的枚举元素并将其分配给0
:
public enum EdibleFarmAnimal {
Invalid = 0,
Sheep = 1,
Cow = 2,
Chicken = 3
}
然后检查您的输入是否有效。多亏了vsevold的回答,我能够理解它为什么要分配它是的值,但是检测场景的解决方案是检查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调用的替代方法。谢谢,这是一个很好的观点,说明了它为什么会拾取该值-您知道是否有任何方法可以在无法解析输入时强制反序列化器拒绝输入,而不是指定默认值?(除了实现我自己的复杂类型解析器之外,对于这样一个基本的验证需求,它似乎过于复杂了)。由于这是一种默认行为,因此您没有太多选择:要么更改枚举,手动检查您的操作字段是否包含适当的值,或实现您的自定义模型绑定感谢您在这方面为我指明了正确的方向(我会给您一个加号,但我还没有足够的声誉!)-事实证明,checking ModelState.IsValid会告诉您什么时候发生了这种情况-请参阅我的答案-这样可以让您干净地处理它。有人愿意评论一下-1的原因吗?