【问题标题】:MVC Model > View Model Design PatternMVC 模型 > 视图模型设计模式
【发布时间】:2015-09-14 11:23:26
【问题描述】:

抱歉,如果这已经得到解答,但我正在寻找处理以下情况时的最佳做法。

我有一个相当大的 MVC5 应用程序,其中包含许多表单/页面。

对于这个例子,假设我有一个像下面这样的病人类(这是一个更大类的精简版)

    Public Class Patient {

    [Display(Name = "Patient Trial Number")]
    public int ID { get; set; }

    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [Display(Name = "Patient DOB")]
    public DateTime PatientDOB { get; set; }

    [Required]
    [Display(Name = "Patient Gender")]
    public Gender PatientGender { get; set; }

    } 

对于需要完成的每个表格,我都有不同的模型。其中一些是非常大的 80 多个属性。

以下是表单模型的精简示例。

public class ExamplePatientForm

    {
        [Key]
        public Patient PatientID { get; set; }

        [Required]
        [Display(Name = "Was Sample One taken?")]
        public bool? SampleOneTaken{ get; set; }

        [Required]
        [Display(Name = "Date Sample One Taken")]
        public DateTime DateSampleOneTaken { get; set; }

        [Required]
        [Display(Name = "Was Sample Two taken?")]
        public bool? SampleTwoTaken{ get; set; }

        [Required]
        [Display(Name = "Date Sample Two Taken")]
        public DateTime DateSampleTwoTaken { get; set; }

        public int PatientRating {get;set;}

        public string Comments { get; set; }


    }

实际上,患者类和个体表单类都大得多。

最初我使用 html.HiddenFor 将 Patient 类的详细信息保存在各个表单中,尽管这感觉不对。

然后我创建了 ViewModel(见下文)

        [Key]
        public int PatientID { get; set; }

        [Required]
        [Display(Name = "Was Sample One taken?")]
        public bool? SampleOneTaken{ get; set; }

        [Required]
        [Display(Name = "Date Sample One Taken")]
        public DateTime DateSampleOneTaken { get; set; }

        [Required]
        [Display(Name = "Was Sample Two taken?")]
        public bool? SampleTwoTaken{ get; set; }

        [Required]
        [Display(Name = "Date Sample Two Taken")]
        public DateTime DateSampleTwoTaken { get; set; }

        public int PatientRating {get;set;}

        public string Comments { get; set; }


    }

ViewModel 删除了关系并将 PatientID 存储为整数。然后我将其映射回控制器中的实体模型。

虽然必须复制每个表单模型来创建视图模型对我来说似乎有点疯狂,尤其是因为有些包含 80 多个属性。

有谁知道解决这个问题的最佳方法?我将有大约 50 个独特的表格。

我还为患者模型创建了一个编辑器模板,这样我就可以在每个表格的顶部显示一些患者信息。但只需要显示某些属性,所以不确定我是否需要为此创建单独的 PatientViewModel 或只是隐藏其他元素。

希望这是有道理的。 任何帮助将不胜感激。

问候, 抢

【问题讨论】:

  • 您可以做的一件事是将您的 VERY LARGE 模型划分为小的 View Model,然后使用向导创建/更新患者。
  • 并显示您可以使用选项卡的信息 - 在顶部显示常用信息和选项卡中的其他信息。 - 每个选项卡都可以使用 Ajax 拥有自己的视图模型加载数据。

标签: c# asp.net-mvc model-view-controller asp.net-mvc-viewmodel


【解决方案1】:

使用viewmodel 显然是最好的方法,您必须在viewmodel 中添加所有这80 多个属性。您不应该直接使用domain model 中的属性。

此外,您的问题似乎是 UI design 问题而不是 programming desing,因此请尝试按照其他人的建议考虑更改您的 UI design。你当然可以把表格分成不同的表格。

还请查看这两个链接,希望它们对您的问题有所帮助
Chris Pratt
Stackoverflow

【讨论】:

    【解决方案2】:

    我强烈建议不要使用您的模型(实体)作为您的视图模型,因为这些模型直接连接到您的 ORM,例如虽然实体框架。这可能意味着如果某人足够狡猾,他们可以更新他们可能不应该访问的属性(尽管 POST 或 GET 请求)。您的域模型也应该非常薄,属性尽可能少 - 没有 DisplayName(...) 之类的。

    如果您的视图模型非常大,您应该将它们拆分并在较小的视图模型上作为属性重用。甚至可能创建一个工厂来建造它们。

    如果需要映射它们,像 AutoMapper 这样的一对一工具会很方便,但我建议手动进行映射或使用简单的自制映射器。

    【讨论】:

      【解决方案3】:

      实际上,没有一个表单可能会同时使用所有 80 个属性。如果是,那么我认为应该将表单分成多个屏幕。

      话虽如此,ViewModel/InputModel 方法绝对是最佳实践。它允许您拥有所有患者属性以及您需要的任何补充信息,例如下拉菜单的项目列表。您可以使用 Automapper 之类的工具为您进行映射,或者您可以手动进行映射,这完全取决于您,并且取决于 ViewModel 和 Domain Model 的匹配程度。我通常只是直接从实体框架中选择我的 ViewModel。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-24
        • 1970-01-01
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        • 2011-10-20
        • 1970-01-01
        相关资源
        最近更新 更多