MVC 模型 > 视图模型设计模式
MVC Model > View Model Design Pattern
很抱歉,如果这个问题已经得到解答,但我正在寻找处理以下情况的最佳实践。
我有一个相当大的 MVC5 应用程序,其中有很多 forms/pages。
对于这个例子,假设我有一个像下面这样的病人 class(这是一个更大 class 的精简版)
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; }
}
实际上,患者 class 和个体 class 都要大很多。
最初我使用 html.HiddenFor 将患者 class 的详细信息保存在各个表格中,尽管这感觉不对。
然后我创建了 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 或只是隐藏其他元素。
希望这是有道理的。
任何帮助将不胜感激。
此致,
罗布
实际上,没有一个表单应该同时使用所有 80 个属性。如果是,那么我认为应该将表单分成多个屏幕。
话虽如此,ViewModel/InputModel 方法绝对是最佳实践。它允许您拥有所有 Patient 属性以及您需要的任何补充信息,例如下拉菜单的项目列表。您可以使用像 Automapper 这样的工具为您做映射,或者您可以手动完成,这完全取决于您,并且取决于 ViewModel 和域模型的匹配程度。我通常只是从 Entity Framework 直接对我的 ViewModel 执行 Select。
我强烈建议不要使用您的模型(实体)作为您的视图模型,因为这些是直接连接到您的 ORM 的模型,例如虽然 Entity Framework。这可能意味着,如果某人足够狡猾,他们可以更新他们可能不应该访问的属性(尽管 POST 或 GET 请求)。您的领域模型也应该非常薄,属性越少越好——没有 DisplayName(...)
之类的。
如果您的视图模型非常大,您应该将它们拆分并作为较小视图模型的属性重新使用。甚至可以创建一个工厂来建造它们。
如果需要一对一映射它们,AutoMapper 之类的工具会很方便,但我建议您手动映射或使用简单的自制映射器。
使用 viewmodel
显然是最好的方法,您必须在 viewmodel
中添加所有这 80 多个属性。您不应直接使用 domain model
中的属性。
此外,您的问题似乎是 UI design
而不是 programming desing
,因此请尝试考虑按照其他人的建议更改您的 UI design
。你肯定可以把表格分成不同的形式。
另请查看这两个链接,希望它们对您的疑虑有所帮助
Chris Pratt
Whosebug
很抱歉,如果这个问题已经得到解答,但我正在寻找处理以下情况的最佳实践。
我有一个相当大的 MVC5 应用程序,其中有很多 forms/pages。
对于这个例子,假设我有一个像下面这样的病人 class(这是一个更大 class 的精简版)
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; }
}
实际上,患者 class 和个体 class 都要大很多。
最初我使用 html.HiddenFor 将患者 class 的详细信息保存在各个表格中,尽管这感觉不对。
然后我创建了 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 或只是隐藏其他元素。
希望这是有道理的。 任何帮助将不胜感激。
此致, 罗布
实际上,没有一个表单应该同时使用所有 80 个属性。如果是,那么我认为应该将表单分成多个屏幕。
话虽如此,ViewModel/InputModel 方法绝对是最佳实践。它允许您拥有所有 Patient 属性以及您需要的任何补充信息,例如下拉菜单的项目列表。您可以使用像 Automapper 这样的工具为您做映射,或者您可以手动完成,这完全取决于您,并且取决于 ViewModel 和域模型的匹配程度。我通常只是从 Entity Framework 直接对我的 ViewModel 执行 Select。
我强烈建议不要使用您的模型(实体)作为您的视图模型,因为这些是直接连接到您的 ORM 的模型,例如虽然 Entity Framework。这可能意味着,如果某人足够狡猾,他们可以更新他们可能不应该访问的属性(尽管 POST 或 GET 请求)。您的领域模型也应该非常薄,属性越少越好——没有 DisplayName(...)
之类的。
如果您的视图模型非常大,您应该将它们拆分并作为较小视图模型的属性重新使用。甚至可以创建一个工厂来建造它们。
如果需要一对一映射它们,AutoMapper 之类的工具会很方便,但我建议您手动映射或使用简单的自制映射器。
使用 viewmodel
显然是最好的方法,您必须在 viewmodel
中添加所有这 80 多个属性。您不应直接使用 domain model
中的属性。
此外,您的问题似乎是 UI design
而不是 programming desing
,因此请尝试考虑按照其他人的建议更改您的 UI design
。你肯定可以把表格分成不同的形式。
另请查看这两个链接,希望它们对您的疑虑有所帮助
Chris Pratt
Whosebug