MVC使用Html.CheckBoxFor带空Bool值

本文关键字:Bool 带空 CheckBoxFor 使用 Html MVC | 更新日期: 2023-09-27 18:17:09

我有一个复选框我想在视图上显示它与一个名为public的字段相关,它表示特定行是否为公共。在数据库中,这是一个位字段,但由于表以前的工作方式,它允许为空。

我正在使用Html。CheckBoxFor但是它抱怨这个字段,因为在系统中它不是bool类型,而是bool类型?类型。我想做的是,如果字段值为null,那么它在前端被视为false(不幸的是,更新数据库值本身不是一个选项)。

我试过使用GetValueOrDefault,并在我的模型文件中放置一个默认值,如下所示:

public class Model
{
    public bool? Public { get; set; }
    public SearchModel()
    { 
        Public = false;
    }
}

然而,它抱怨这个,给我以下错误:

An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

所以我不知道我该如何从这里进步,有人能帮我指出正确的方向吗?

编辑:

这是我试图用来显示复选框的视图上的代码。在这个例子中,我添加了一些额外的html属性,使它看起来像一个切换,而不是一个简单的复选框:

Html.CheckBoxFor(model => model.Public, new {data_toggle = "toggle", data_off = "No", data_on = "Yes", data_size = "small"})

MVC使用Html.CheckBoxFor带空Bool值

当您将表达式传递给无法求值的模板化帮助程序时,将发生特定的异常。请记住,当您使用基于表达式的helper时,您实际上不是通过值传递属性,而是通过表示模型上的属性的表达式,并且helper将使用该表达式来引用该属性,从中生成字段名等。

你没有显示你做这个的实际代码,但这意味着基本上你不能做这样的事情:

@Html.EditorFor(m => m.Public.GetValueOrDefault())

因为模板化的助手无法将其解析为与模型上的属性匹配的表达式。

至于这里的实际基本关注点,即如果值为null,则将其设置为false,您只需要自定义getter和setter。@utaco的回答提供了c# 6.0新的更简单的自动实现属性的方法:

public bool? Public { get; set; } = false;

对于以前版本的c#,您需要以下内容:

private bool? public;
public bool? Public
{
    get { return public ?? false; }
    set { public = value; }
}

但是,当您不打算将Public实际为空时,将其保留为可空bool只会使您的代码更加困难。假设您可以将其更改为bool(即,这是一个视图模型,而不是绑定到数据库表的实际实体类),那么您应该这样做。但是,您仍然希望将private保留为可空的。这允许您在setter中接受空值,但在getter中强制将它们转换为false值,这意味着public的实际值将始终是truefalse,即不为空。

如果你使用c# 6.0或更高版本,你可以使用:

public bool YourProp { get; set; } = false; 

我采用了Chris Pratt的想法,但使用方式不同。我创建了一个ViewModel,并添加了一个非空属性来更新空属性,反之亦然。

public bool? Public { get; set; }
private bool _public;
public bool _Public
{
    get { return Public ?? false; }
    set 
    { 
      _public = value; 
      Public = value; 
    }
}

现在在视图中,您将使用非空值来更新,而不是使用可空值

Html.CheckBoxFor(model => model._Uploaded)

这种方法的唯一问题是,如果保存更改,您将不会返回null。这对我来说很有效,因为在我们的程序中NULL值表示false。

不需要初始化。@Html.EditorFor(m => m.AnyNullableProperty)

        <div class="form-group">
            @Html.LabelFor(model => model.RequiresBatchNumberOnReceipt, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(m => m.RequiresBatchNumberOnReceipt)
                @Html.ValidationMessageFor(model => model.RequiresBatchNumberOnReceipt)
            </div>
        </div>