Asp.net mvc 如何覆盖ASP.NETMVC';s默认模型绑定器,以便绑定到不可为空的值类型的空值赢得';不会触发模型验证错误

Asp.net mvc 如何覆盖ASP.NETMVC';s默认模型绑定器,以便绑定到不可为空的值类型的空值赢得';不会触发模型验证错误,asp.net-mvc,model-binding,Asp.net Mvc,Model Binding,我在ASP.Net MVC中发现了一件非常令人沮丧的事情,即默认模型绑定器在将空(字符串或null)值绑定到不可为null的值类型时隐式地应用了必需的注释,而不是简单地将目标保留为其默认值,或者至少提供一个选项,让这成为默认行为 如果将模型上的目标属性类型更改为可空值很不方便,那么允许默认模型绑定器直接跳过将空值绑定到不可空值类型的尝试的最短代码量是多少?我假设我需要子类化DefaultModelBinder,但我不确定需要重写什么来实现所需的行为 例如: <input type="tex

我在ASP.Net MVC中发现了一件非常令人沮丧的事情,即默认模型绑定器在将空(字符串或null)值绑定到不可为null的值类型时隐式地应用了
必需的
注释,而不是简单地将目标保留为其默认值,或者至少提供一个选项,让这成为默认行为

如果将模型上的目标属性类型更改为可空值很不方便,那么允许默认模型绑定器直接跳过将空值绑定到不可空值类型的尝试的最短代码量是多少?我假设我需要子类化
DefaultModelBinder
,但我不确定需要重写什么来实现所需的行为

例如:

<input type="text" name="MyField"/>
应允许属性
MyField
保留其默认值
0
,因为表单中已过账空值


假设我不能简单地更改属性类型a
Nullable

这样的东西怎么样?(免责声明:未进行任何程度的信心测试)

理论上,这个想法是确定
DefaultModelBinder
分配给属性的值,检查它是否为空值,然后将其分配给要绑定的
ValueType
的默认值

这将防止绑定器添加
ModelState
错误,并且仍然不会影响其他属性的验证,例如
[Range]


我建议更进一步,创建自己的属性(即,
非必需属性
)。然后,在自定义模型活页夹中,您可以检查属性是否具有新的
非必需的
属性,如果有,则仅执行此自定义代码;你想要的行为对我来说是开箱即用的。如果模型绑定器绑定的是“空”值,那么绑定的值是什么?当文本框为空时,将以空字符串形式接收发布的值。空字符串不会绑定到(例如)decimal类型,因为没有处理它的转换。我希望公约只是不要试图约束它。这不是我正在经历的行为,或者我不理解,或者我没有准确地再现你的情况。查看此屏幕截图:我在表单中添加了
Field1
,这是一篇使用查询字符串的帖子。我应该补充一点,我看到了您提到的modelstate错误(
Field1
是必需的)服务器端。我想现在看看你文章的标题,这就是你想要避免的你在使用客户端javascript验证吗?这是一个选项,尽管感觉有点不可靠,好像我只是想假装问题不存在。如果没有其他解决方案,我会选择它,不过如果用户可以将他们不关心的字段留空就好了。
public ActionResult MyAction(MyModel model)
{
    // do stuff
}

public class MyModel
{
    public int MyField { get; set; }
}
public class NonRequiredModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        var result = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
        if (result == null && propertyDescriptor.PropertyType.IsValueType)
            return Activator.CreateInstance(propertyDescriptor.PropertyType);

        return result;
    }
}