我有一个复选框,我希望在与名为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"})
答案 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的实际值将始终为true
或false
,即不为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。