我有一个名为S2kBool的自定义对象,可以转换为常规布尔对象。基本上,它允许我的应用程序以与处理C#布尔值相同的方式处理遗留数据库中的布尔值。然后问题是,当我尝试使用复选框来设置S2kBool属性的值时,它会失败。
这样的代码有效:
public class MyClass {
public S2kBool MyProperty { get; set; }
}
MyClassInstance.MyProperty = true;
但它几乎就像UpdateModel期望一个实际的bool类型,而不是一个可以转换为bool的对象。然而,我无法分辨,因为抛出的异常是如此模糊:
模型未成功更新。
我该如何解决这个问题?我需要自定义ModelBinder吗?
谢谢!
答案 0 :(得分:2)
如果设置更改了S2kBool属性的值,则可以使用bool类型的其他bool属性。
public class MyClass {
public S2kBool MyProperty { get; set; }
public bool MyPropertyBool {
get
{
return (bool)MyProperty;
}
set
{
MyProperty = value;
}
}
}
然后你的html表单中只有MyPropertyBool,而且模型绑定器不会对它的类型感到不满。
我将此技术用于密码和放大器等属性。 HashedPassword其中Password是ModelBinder绑定的html表单中的属性,在Password的setter中,它将HashedPassword设置为它的哈希值,然后将其保存到数据库或者其他任何内容。
答案 1 :(得分:2)
虽然Charlino的解决方案很聪明并且可行,但我个人不喜欢为了这个目的而使用额外属性“弄脏”我的域实体的想法。我认为你已经得到了答案:自定义模型绑定器。类似的东西:
public class S2kBoolAttribute : CustomModelBinderAttribute, IModelBinder
{
public override IModelBinder GetBinder()
{
return this;
}
public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext )
{
ValueProviderResult result;
return bindingContext.ValueProvider.TryGetValue( bindingContext.ModelName, out result )
? (S2kBool)result.ConvertTo( typeof( bool ) )
: null;
}
}
然后您可以将控制器操作修改为:
public ActionResult Foo( [S2kBool]S2kBool myProperty ){
myClassInstance.MyProperty = myProperty;
SaveToLegacyDb(myClassInstance);
return RedirectToAction("Bar");
}
如果你在模型绑定器中加入更多的工作,你可以让它与全局注册的活页夹一起工作 - 但我上面给你的实现应该适用于在需要时挑选出值。