【问题标题】:How to override ASP.Net MVC's default model binder so that an empty value bound to a non-nullable value type won't trigger a model validation error如何覆盖 ASP.Net MVC 的默认模型绑定器,以便绑定到非可空值类型的空值不会触发模型验证错误
【发布时间】:2012-10-03 10:01:43
【问题描述】:

在 ASP.Net MVC 中我发现非常令人沮丧的是,默认模型绑定器在将空(字符串或 null)值绑定到不可为空的值类型时隐式应用 Required 注释,而不是简单地离开具有默认值的目标,或者至少提供一个选项以允许其成为默认行为。

考虑到将模型上的目标属性类型更改为可空值不方便的情况,我可以使用的最短代码量是多少,以允许默认模型绑定器简单地跳过将空值绑定到不可为空的值类型?我假设我需要继承 DefaultModelBinder,但我不确定我需要重写什么来实现所需的行为。

示例:

<input type="text" name="MyField"/>

不带值提交:

public ActionResult MyAction(MyModel model)
{
    // do stuff
}

public class MyModel
{
    public int MyField { get; set; }
}

应该允许属性MyField 保留其默认值0,因为从表单中发布了一个空值。

假设我不能简单地将属性类型更改为Nullable&lt;int&gt;

【问题讨论】:

  • 我正在使用 mvc3;你想要的行为对我来说是开箱即用的。如果模型绑定器绑定了一个“空”值,它绑定的是什么值?
  • 当文本框为空白时,发布的值作为空字符串接收。空字符串不会绑定到(例如)十进制类型,因为没有转换来处理它。我希望约定是简单地不尝试绑定它。
  • 那不是我正在经历的行为,或者我不明白,或者我没有完全重现你的情况。看到这个截图:imgur.com/xXqib 我在表单中添加了Field1,这是一个使用查询字符串的 POST
  • 我应该补充一点,我看到你提到的模型状态错误(Field1 是必需的)服务器端。我想现在看看你帖子的标题,这就是你想要避免的。 :) 你在使用客户端 javascript 验证吗?
  • 这是一个选项,虽然感觉有点狡猾,就像我只是想假装问题不存在。如果没有其他解决方案,我会选择它,但如果用户可以将他们不关心的字段留空,那就太好了。

标签: asp.net-mvc model-binding


【解决方案1】:

这样的事情怎么样? (免责声明:未经任何可信度测试)

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;
    }
}

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

这应该可以防止binder添加ModelState错误,并且仍然不会影响[Range]等其他属性的验证

我建议更进一步并创建您自己的属性(即NonRequiredAttribute)。然后在您的自定义模型绑定器中,您可以检查该属性是否具有新的NonRequired 属性,并在有的情况下执行此自定义代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多