Asp.net mvc 使用ViewModel屏蔽可为空的域属性

Asp.net mvc 使用ViewModel屏蔽可为空的域属性,asp.net-mvc,asp.net-mvc-3,viewmodel,nullable,Asp.net Mvc,Asp.net Mvc 3,Viewmodel,Nullable,我正在使用EntityFramework4.0,并使用POCO对象。当我从DB中填充POCO对象时,我将属性值转换为我自己的域对象,我们可以称之为我的模型 当然,我的模型的字段是否可以为NULL取决于它在数据库中映射到的值是否来自NULL或notnull列。我将不详细介绍,但这些值在DB中必须可以为null,因为用户可以在将对象发布给公众之前部分保存该对象的草稿。在这种情况下,我有几个字段可以为空。假设我的模型看起来像: public class MyModel { public int?

我正在使用EntityFramework4.0,并使用POCO对象。当我从DB中填充POCO对象时,我将属性值转换为我自己的域对象,我们可以称之为我的模型

当然,我的模型的字段是否可以为NULL取决于它在数据库中映射到的值是否来自NULL或notnull列。我将不详细介绍,但这些值在DB中必须可以为null,因为用户可以在将对象发布给公众之前部分保存该对象的草稿。在这种情况下,我有几个字段可以为空。假设我的模型看起来像:

public class MyModel
{
   public int? Field1 {get; set; }
   public DateTime? Field2 {get; set; }
   public int Field3 {get; set; }
}
如果我在视图中使用这个模型,并带有可为空的字段,我会收到一些错误,告诉我不能在不同的地方使用可为空的属性作为值,比如HTML帮助程序等。我可以说类似于
If(Model.MyBoolField.HasValue&&Model.MyBoolField.Value){//etc}
,但是对于一个视图来说,这感觉很笨重

我考虑创建一个ViewModel对象,该对象继承自我的原始域对象,并且具有我的可空字段的新的不可空版本,如果基本版本为空,则返回适当的值。比如:

public class MyViewModel : MyModel
{
   public new int Field1
   {
      get { return base.Field1 ?? 7; }
   }

   public new DateTime Field2
   {
      get { return base.Field2 ?? DateTime.Now; }
   }
}
我的问题是,我并不总是知道一个好的“默认”值来显示。当基值为null时,如果我在视图模型的getter中抛出一个异常会怎么样?那是糟糕的做法吗


我基本上是在寻找如何处理模型中的可空字段的最佳实践,尤其是在视图中显示时。

如果只需要在视图中显示这些字段,则无需指定或检查is是否有值

在视图文件中使用
Model.Field1
就足够了。它不会显示任何内容,也不会抛出异常。在有意义时,您始终可以使用
??
设置默认值

@(Model.Field1 ?? "There is nothing to see here")

在大多数情况下,我使用“For”帮助程序,它似乎与
null
值一致(
PublishedCount
是一个null属性):

当我只需要使用
TextBox
时,我使用
GetValueOrDefault
方法,使用框架提供的任何默认值:

@Html.TextBox("BillPull.AutoPublishDate", Model.BillPull.AutoPublishDate.GetValueOrDefault().ToString(dateFormat), new { id = "dtpAutoPublishDate" })
@Html.ValidationMessageFor(m => m.BillPull.AutoPublishDate)

我不知道这是否有帮助,但如果您使用POCO对象并使用
DisplayFormat
属性设置
ConvertEmptyStringToNull
NullDisplayText
对其进行修饰,您可能会得到您想要的行为。在这种情况下,lambda表达式可能更具可读性
@Html.ValidationMessageFor(m=>m.BillPull.PublishedCount)
@Html.TextBox("BillPull.AutoPublishDate", Model.BillPull.AutoPublishDate.GetValueOrDefault().ToString(dateFormat), new { id = "dtpAutoPublishDate" })
@Html.ValidationMessageFor(m => m.BillPull.AutoPublishDate)