2

我有一个名为 S2kBool 的自定义对象,可以与常规布尔对象相互转换。基本上,它允许我的应用程序以与处理 C# 布尔值相同的方式处理遗留数据库中的布尔值。然后问题是,当我尝试使用复选框设置 S2kBool 属性的值时,它失败了。

像这样的代码有效:

public class MyClass {
    public S2kBool MyProperty { get; set; }
}

MyClassInstance.MyProperty = true;

但这几乎就像 UpdateModel 期待一个实际的 bool 类型,而不是一个可以转换为 bool 的对象。但是,我真的不能说,因为抛出的异常是如此模糊:

模型未成功更新。

我怎样才能解决这个问题?我需要自定义 ModelBinder 吗?

谢谢!

4

2 回答 2

2

您可以拥有一个额外的 bool 类型的 bool 属性,当设置它时会更改您的 S2kBool 属性的值。

public class MyClass {
    public S2kBool MyProperty { get; set; }
    public bool MyPropertyBool {
        get
        {
            return (bool)MyProperty;
        }
        set
        {
            MyProperty = value;
        }
    }
}

然后,您只需在 html 表单中使用 MyPropertyBool ,modelbinder 就不会因为它的类型而吓坏了。

我将这种技术用于诸如 Password 和 HashedPassword 之类的属性,其中 Password 是 ModelBinder 绑定到的 html 表单中的属性,在 Password 的 setter 中,它将 HashedPassword 设置为它的哈希值,然后将其持久化到数据库或其他任何地方。

于 2009-02-26T02:00:46.300 回答
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");
}

如果您在模型绑定器中投入更多的工作,您可以让它与全局注册的绑定器一起工作——但是我上面给您的实现应该可以在需要时用于挑选值。

于 2009-02-26T16:58:30.573 回答