Asp.net mvc 3 ASP.NET MVC3 ValueProvider将字符串输入拖放到双精度属性
我正在尝试验证一个文本框的输入,该文本框对应于我的模型中类型为Asp.net mvc 3 ASP.NET MVC3 ValueProvider将字符串输入拖放到双精度属性,asp.net-mvc-3,model-binding,value-provider,Asp.net Mvc 3,Model Binding,Value Provider,我正在尝试验证一个文本框的输入,该文本框对应于我的模型中类型为double的属性。如果用户输入了“foo”,我想了解它,以便显示错误。但是,ValueProvider正在无声地删除该值(没有错误添加到ModelState) 在正常提交中,我为myDouble对应的文本框填写“2”,然后提交表单。 检查controllerContext.HttpContext.Request.Form显示myDouble=2,以及其他正确的输入bindingContext.ValueProvider.GetVal
double
的属性。如果用户输入了“foo”
,我想了解它,以便显示错误。但是,ValueProvider
正在无声地删除该值(没有错误添加到ModelState
)
在正常提交中,我为myDouble
对应的文本框填写“2”
,然后提交表单。
检查controllerContext.HttpContext.Request.Form
显示myDouble=2
,以及其他正确的输入<代码>bindingContext.ValueProvider.GetValue(“myDouble”)==2,如预期的那样。bindingContext.ModelState.Count==6
和bindingContext.ModelState[“myDouble”].Errors.Count==0
。一切都很好,模型按预期绑定
然后我在myDouble
对应的文本框中填写“foo”,并提交表单。
检查controllerContext.HttpContext.Request.Form
显示myDouble=foo
,这正是我所期望的。但是,bindingContext.ValueProvider.GetValue(“myDouble”)==null
和bindingContext.ModelState.Count==5
(确切数字并不重要,但比以前少了一个)。查看ValueProvider
,就好像从来没有提交过myDouble
,模型绑定也像没有提交一样发生。这使得很难区分错误输入和无输入
这是
ValueProvider
的预期行为吗?有没有一种方法可以让ValueProvider
在转换失败时报告,而不实现自定义ValueProvider
?谢谢 这里的部分问题是您的模型有一种类型为double
问题是,double
不能为空,因此默认值为0,因此在提交时。。如果ValueProvider
返回null,则该字段的值仍然为0,验证将通过
您应该使用
double?
使double
可为空,然后向属性添加必需的属性。如果不需要该类型,则可以添加正则表达式验证器。这里的部分问题是您的模型的类型为double
问题是,double
不能为空,因此默认值为0,因此在提交时。。如果ValueProvider
返回null,则该字段的值仍然为0,验证将通过
您应该使用
double?
使double
可为空,然后向属性添加必需的属性。如果不需要该类型,则可以添加正则表达式验证器。可以通过实现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();
}
您可以通过实现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();
}
用RequiredAttribute修饰字段。你能为模型显示一点代码和视图所需的一点代码吗,因为我已经测试了它和
ModelState。对于double
接收文本,IsValid
是false
。@Silvermind-你确定你不是指double吗?
@MystereMan对不起,我的错了。我的意思是文本要双重提交,但我在ASP.NET MVC4;)上测试了它@Silvermind-我想这还不清楚。这个位于代码括号内,表示可为空的双精度。你确定你不是指可为null的double吗?
而是double
?用RequiredAttribute修饰字段。你能为模型显示一点代码和视图所需的那一点吗,因为我已经对它进行了测试,并且ModelState.IsValid
对于double
接收文本是false
。@Silvermind-你确定你不是说double吗?
@MystereMan对不起,我的错了。我的意思是文本要双重提交,但我在ASP.NET MVC4;)上测试了它@Silvermind-我想这还不清楚。这个位于代码括号内,表示可为空的双精度。你确定你不是指一个可空的double吗?
而是double
?很好的解决方案。奇怪的行为对验证器来说很难。我还是要签入MVC4,因为我很好奇它是否也发生在那里。ASP.NET MVC4会正确处理它,因此,将文本提交到非属性且不可为空的double
属性将设置ModelState.IsValid=false
,并显示以下消息:值“foo”对MyDouble无效。
@Silvermind-感谢您的关注。我不知道这是否是一种进步MVC4@MystereMan谢谢,将MyDouble
更改为键入double?
,并用[必需]
对其进行了装饰。ModelState
返回无效,错误为“需要MyDouble”
。这不是对实际发生的事情的最准确描述,但在我的例子中已经足够好了,可以确定提交了一个错误的输入。@Silvermind这是个好消息。一旦我们升级,我很乐意清理这个补丁。很好的解决方案