MVC使用Html.CheckBoxFor和可以为空的Bool

时间:2016-11-08 14:55:55

标签: c# asp.net-mvc

我有一个复选框,我希望在与名为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"})

4 个答案:

答案 0 :(得分:10)

当您将表达式传递给无法评估的模板化帮助程序时,会发生您遇到的特定异常。请记住,当您使用基于表达式的帮助程序时,您实际上并没有按值传递属性,而是在模型中表示属性的表达式,以及帮助器将用于引用该属性,从等生成字段名称

您还没有显示您执行此操作的实际代码,但这实际上意味着您无法执行以下操作:

@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实际上是null,那么你的代码会变得更加困难。假设您可以将其更改为bool(即这是一个视图模型,而不是与数据库表绑定的实际实体类),那么您应该这样做。你仍然希望将私有保留为可空。这允许您接受setter中的null,但是将它们强制转换为getter中的false值,这意味着public的实际值将始终为truefalse,即不为null。

答案 1 :(得分:3)

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

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

答案 2 :(得分:0)

这不需要初始化。 @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>

答案 3 :(得分:0)

我接受了克里斯·普拉特(Chris Pratt)的想法,但使用的方式有所不同。我创建了一个ViewModel并添加了一个不可为null的属性来更新可为null的属性,反之亦然。

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。