3

我是 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
4

1 回答 1

1

好的,那么一些建议。

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

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

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 编辑器模板(这完全是另一个主题,但谷歌它可以找到许多涵盖该主题的主题)。这为您提供了比呈现类似类型(即日期时间)的元素更大的灵活性和可重用性。

但是,除了使用它之外,您还可以向模型添加另一个属性,并使用 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 条件。

于 2012-11-13T21:55:23.680 回答