我正在尝试验证文本框的输入,该文本框对应于模型中double
类型的属性。如果用户输入"foo"
我想知道它,那么我可以显示错误。但是,ValueProvider
正在静默删除值(没有错误添加到ModelState
)。
在正常提交中,我填写"2"
以查找与myDouble
对应的文本框并提交表单。
检查controllerContext.HttpContext.Request.Form
会显示myDouble=2
以及其他正确的输入。正如预期的那样bindingContext.ValueProvider.GetValue("myDouble") == 2
。 bindingContext.ModelState.Count == 6
和bindingContext.ModelState["myDouble"].Errors.Count == 0
。一切都很好,模型按预期结合。
然后我为“{1}}对应的文本框填写”foo“并提交表单。
检查myDouble
会显示controllerContext.HttpContext.Request.Form
,这是我的预期。但是,myDouble=foo
和bindingContext.ValueProvider.GetValue("myDouble") == null
(确切的数字并不重要,但它比以前少了一个)。查看bindingContext.ModelState.Count == 5
,就好像ValueProvider
从未提交过,模型绑定就好像不是一样。这使得难以区分输入错误和无输入。
这是myDouble
的预期行为吗?有没有办法让ValueProvider
报告转化失败而不实施自定义ValueProvider
?谢谢!
答案 0 :(得分:1)
此处的部分问题是您的模型的类型为double
。
问题是double
不能为空,因此默认值为0,因此提交..如果ValueProvider
返回null,则该字段的值仍为0,验证将通过。
您应该使用double
使double?
为空,然后将属性添加到必需属性中。如果不需要该类型,则可以添加正则表达式验证器。
答案 1 :(得分:0)
您可以通过实现IModelBinder来实现自定义模型绑定逻辑。这将使数据验证逻辑处于模型绑定级别 - 因此可用于任何类型的ValueProvider。在您的情况下,模型绑定器将确定当myDouble =“foo”不是double时,并向显示无效值的ModelState错误添加异常。
public class CustomDoubleBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
decimal tempDouble = 0m;
if (bindingContext.ValueProvider.GetValue(bindingContext.ModelName) != null)
{
if (double.TryParse(bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue, out tempDecimal))
{
bindingContext.ModelState[bindingContext.ModelName].Errors.Add("Error parsing double value: " + bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue);
}
}
return tempDouble;
}
}
创建此自定义模型绑定器后,您需要在Global.asax中注册它:
protected void Application_Start()
{
ModelBinders.Binders[typeof(double)] = new CustomDoubleBinder();
}