我正在使用一个匹配表单中所有字段的对象。然后我使用默认绑定来填充我的操作中的对象,就像这样;
public ActionResult GetDivisionData(DivisionObj FormData)
我的DivisionObj在构造函数中将其所有值初始化为string.empty。
问题是当活页夹从发布的表单数据填充模型时,任何未发布的数据在对象中都设置为null,尽管我初始化对象以包含空字符串。
有没有办法改变这一点,以便未发布的数据将是一个空字符串。
答案 0 :(得分:13)
这是DefaultModelBinder的默认行为,更具体地说是DataAnnotations框架。默认情况下, ConvertEmptyStringToNull 设置为true。您可以创建自己的模型装订器并替换默认的模型装订器。
public class EmptyStringModelBaseBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
return base.BindModel(controllerContext, bindingContext);
}
}
然后在全球......
ModelBinders.Binders.DefaultBinder = new EmptyStringModelBaseBinder();
虽然我希望他们有一种静态的方法来为默认的模型绑定器设置它。也许在v3 :)
或者,您也可以使用[DisplayFormat(ConvertEmptyStringToNull=false)]
属性按属性设置此值。
答案 1 :(得分:2)
您始终可以使用[Bind(Exclude="PropertyName1,PropertyName2,PropertyName3")]
从绑定中排除某些属性:
public ActionResult GetDivisionData([Bind(Exclude="PropertyName1,PropertyName2,PropertyName3")]DivisionObj FormData)
如果你真的必须在String属性中使用String.Empty,则可以使用此绑定器:
public class EmptyStringModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
if (propertyDescriptor.PropertyType == typeof(String))
propertyDescriptor.SetValue(bindingContext.Model,propertyDescriptor.GetValue(bindingContext.Model) ?? String.Empty);
}
}
你还必须在global.asax中运行它:
ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder();
答案 2 :(得分:1)
我只能确认我看到的结果和你一样。您的选择是:
一种方法是排除LukLed解释的属性。但这会导致代码重复,每次DivisionObj(或任何其他你想装饰的Model类)都显示为action参数时,你必须在每个控制器动作上执行此操作。所以它有点麻烦......
我目前正在处理各种自定义属性的多个问题,一些需要在构造函数中实例化,一些需要在运行时才知道的值,另一些在某种程度上也是特殊的。
我已经确定对我来说最好使用Custom Model Binder并在那里完成大部分工作。