【问题标题】:UpdateModel won't properly convert a boolean valueUpdateModel 不会正确转换布尔值
【发布时间】:2009-02-25 21:38:32
【问题描述】:

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

这样的代码可以工作:

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

MyClassInstance.MyProperty = true;

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

模型未成功更新。

我该如何解决这个问题?我需要自定义 ModelBinder 吗?

谢谢!

【问题讨论】:

    标签: c# asp.net-mvc updatemodel


    【解决方案1】:

    虽然 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");
    }
    

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

    【讨论】:

    • 假设您永远不想将 S2kBool 类型的属性与任何其他模型绑定器绑定,我会将自定义绑定器添加到该类型的 global.asax 应用程序启动事件中的集合中,而不是使用在动作本身中绑定属性。
    • 通过在 global.asax 中添加自定义模型绑定器,它会自动应用于所有 S2kBool 属性吗?例如,在我上面给出的代码中,如果我试图将数据绑定到 MyClass,我的模型绑定器会应用于 MyClass.MyProperty,还是仅适用于方法参数?
    【解决方案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 设置为它的哈希值,然后将其持久化到数据库或其他任何东西.

    【讨论】:

      猜你喜欢
      • 2021-11-26
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 2018-01-24
      • 2021-06-27
      • 2013-11-22
      相关资源
      最近更新 更多