反序列化和验证阶段检测到的错误经常混淆。
假设你有以下enum:
public enum MyEnum
{
None,
Value1,
Value2
}
以下型号:
public class TestModel
{
[Required]
public int? Id { get; set; }
[EnumDataType(typeof(MyEnum), ErrorMessage = "Custom Error Message")]
public MyEnum MyEnumProp { get; set; }
}
当您发布数据时:
{
"Id": 123,
"MyEnumProp": "UnexistingEnumValue"
}
错误将在反序列化阶段发生(在这种情况下,在 Json.NET 中)。反序列化器无法将字符串 "UnexistingEnumValue" 转换为来自 MyEnum 的某些值。
在这种情况下,反序列化器将注册以下模型绑定错误:Requested value 'UnexistingEnumValue' was not found。
ModelState.IsValid 将设置为 false,但 MyEnumProp 的值将保留其默认值 MyEnum.None。由EnumDataType 属性执行的验证不会检测到任何错误,因为MyEnum.None 是MyEnum 的有效值。这就是为什么您不会在ModelState 错误中看到"Custom Error Message"。
现在,如果您发布以下数据:
{
"Id": 123,
"MyEnumProp": 5
}
在反序列化阶段不会发生错误,因为即使没有多大意义,下面的赋值也是相当合法的:
MyEnum v = (MyEnum)5;
所以反序列化器不会检测到任何错误。但是现在EnumDataType 验证开始发挥作用。它检测到5 不是MyEnum 的有效值。 ModelState.IsValid 设置为 false 并注册了 EnumDataType.ErrorMessage 中指定的错误消息 ("Custom Error Message")。
如果您希望为反序列化和验证错误提供相同的自定义消息,您应该提升到反序列化器 (Json.NET) 的级别并为此目的使用其扩展点。