【问题标题】:MVC3 format nullable DateTime in TextBoxFor without changing modelTextBoxFor中的MVC3格式可为空的DateTime而不更改模型
【发布时间】:2012-11-14 06:21:51
【问题描述】:

我是 MVC3 的新手,并且仍在努力学习良好的编程实践。我有一段时间试图格式化 DateTime?显示在我的 MVC3 项目中,该项目没有与日期来源的类关联的显式 ModelName.cs 文件。

我们已经有一个数据库,并使用一个 .edmx(我们的称为 Pooling.edmx)来获取我们的模型。我显然不想编辑设计器文件以适应这个被广泛接受的解决方案:Date only from TextBoxFor()

然后我尝试了另一个解决方案,我在这里找到了:Using Html.TextBoxFor with class and custom property (MVC)

使用:

@Html.TextBoxFor(m => m.Name, new { data_bind="value: Name", @class = "title width-7" })

这很有效,因为我能够使用自定义属性、添加类名并一次性设置一个值。

我改变了这个:

@Html.TextBoxFor(m => Model.PrePoolOwner.OglDateEffective, new Dictionary<string, object> { { "class", "check-dirty input-small datePicker" }, { "data-original-value", @Model.PrePoolOwner.OglDateEffective } })

进入这个(这看起来真的很丑......并导致我提出问题):

@Html.TextBoxFor(m => Model.PrePoolOwner.OglDateEffective, new { data_original_value = Model.PrePoolOwner.OglDateEffective.HasValue ? Model.PrePoolOwner.OglDateEffective.Value.ToString("MM/dd/yyyy") : null, @class = "datePicker check-dirty", @Value = Model.PrePoolOwner.OglDateEffective.HasValue ? Model.PrePoolOwner.OglDateEffective.Value.ToString("MM/dd/yyyy") : null })

是更好地查找和使用这些其他方式(例如下划线将转换为破折号等)来显示信息,还是我应该拥有一个 ModelName.cs 文件来更改它在模型级别的显示方式?

出于某种原因,我觉得拥有一个庞大的 Pooling.edmx 文件来映射我们的数据库,现在和将来都会限制我们随着网站的发展而访问/呈现/更改数据的方式。

要获得上面由 Model.PrePoolOwner.OglDateEffective 调用的“PrePoolOwner”对象,我们有一个 PrePoolOwnerRow.cs 文件,它可以:

namespace OCC_Tracker.Models
{
    public class PrePoolOwnerRow
    {
        public bool Dirty { get; set; }
        public bool Delete { get; set; }

        public PrePoolOwner PrePoolOwner { get; set; }

        public PrePoolOwnerRow(PrePoolOwner owner)
        {
            this.Dirty = false;
            this.Delete = false;
            this.PrePoolOwner = owner;
        }

        public PrePoolOwnerRow()
        { }
    }
}

然后我们在 .cshtml 文件的顶部调用

@model OCC_Tracker.Models.PrePoolOwnerRow

【问题讨论】:

  • 您是否将视图绑定到 .edmx 模型?如果是这样,你永远不应该这样做——总是创建视图模型来绑定到你的 MVC 视图。
  • 是的,听起来您将视图绑定到域/实体模型。您应该在 MVC 项目中设置单独的视图模型,然后将您的域/实体模型映射到视图模型。
  • 阅读 this article 帮助我了解了视图模型与域模型。
  • @JeradRose(编辑问题以显示我的代码示例) - 谢谢。我的理解是正确的:如果我们想要一个类(比如上面的 PrePoolOwner),我们需要创建一个新的模型文件,将它在数据库中的每个字段映射到新的模型文件,然后在我们的 . cshtml 文件?
  • OCC_Tracker 是您的 MVC 应用程序,还是您的 edmx?通常,是的,您需要一个代表视图中数据的模型(可能与您的域模型 [数据库] 非常相似,也可能不相似)。但是不要仅仅创建与域模型相同的视图模型——只定义你的视图需要什么,并以对你的视图有意义的方式构造它(这可能意味着扁平化/非规范化你的域模型)。查看 AutoMapper 以了解视图和域模型之间的映射。

标签: c# asp.net-mvc-3 datetime formatting


【解决方案1】:

好的,有一些建议。

首先,在您的示例中,PrePoolOwnerRow 是您的视图模型。这本身很好。但是代码异味是您通过视图模型PrePoolOwnerRow 暴露PrePoolOwner(域实体)的地方。

所以我建议的第一件事是将您的视图模型更新为更像这样的东西:

public class PrePoolOwnerModel
{
    public bool Dirty { get; set; }
    public bool Delete { get; set; }

    public DateTime? OglDateEffective { get; set; }
    public String OglDateEffective { get; set; }

    // Other public properties here that map to properties on your PrePoolOwner entity.
}

我在这里所做的只是删除对域模型的引用,并将其替换为您的视图所需的模型中的属性(占位注释)。

在您的控制器中,获取您的 PrePoolOwner 模型,并使用 AutoMapper 将其映射到您的视图模型(这是一个假设示例,因为我不知道您的视图在做什么):

public ViewResult Index(int id)
{
    PrePoolOwner entity = myservice.GetPrePoolOwner(id);

    PrePoolOwnerModel model = Mapper.Map<PrePoolOwnerModel>(entity);

    return View(model);
}

现在,要使用 DateTime 文本框解决问题,您应该考虑使用 MVC 编辑器模板(这完全是另一个主题,但Google it 可以找到许多涵盖该主题的主题)。这使您在呈现类似类型(即 DateTime)的元素时具有更大的灵活性和可重用性。

但是,除了使用它之外,您还可以向模型添加另一个属性,并使用 AutoMapper 适当地设置 DateTime。所以,在你的控制器中是这样的,除了你会在 AutoMapper 中设置一个映射来处理这个:

public class PrePoolOwnerModel
{
    ....
    public String OglDateEffectiveValue { get; set; }
    ....
}

public ViewResult Index(int id)
{
    ....
    model.OglDateEffectiveValue = model.OglDateEffective.HasValue ? 
                                  model.OglDateEffective.Value.ToString("MM/dd/yyyy") : 
                                  String.Empty;
    ....
}

设置完成后,您可以将这个新模型属性 (OglDateEffectiveValue) 用于文本框上的属性。

我知道我在那里介绍了很多内容,但是请深入研究并尝试像这样对您的视图模型进行建模,并使用 AutoMapper 将数据映射到您的视图模型完全就像您需要的那样在你看来。

保持视图逻辑非常简单。避免在场合循环之外使用任何疯狂的东西,也许在这里或那里使用 if 条件。

【讨论】:

  • 感谢您说得非常清楚!这对我很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
  • 2020-04-13
  • 1970-01-01
相关资源
最近更新 更多