MVC架构 - 重新使用相同的viewmodel进行读取和编辑

dro*_*gon 5 architecture model-view-controller asp.net-mvc viewmodel

假设我们有以下(过于简单)的场景:

我们有一个屏幕来查看人员详细信息和一个屏幕来编辑人员详细信息.

屏幕显示人员详细信息具有以下字段(仅显示):

名字姓氏生物

屏幕编辑人员详细信息显示有以下字段(在输入控件中):

ID(隐藏)名字姓氏生物

假设我们的显示视图模型如下所示:

    public class DisplayPersonViewModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Bio { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我们的编辑视图模型如下所示:

public class EditPersonViewModel
{
    [Required]
    public int ID { get; set; }

    [Required]
    [StringLength(20)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(20)]
    public string LastName { get; set; }

    [Required]
    public string Bio { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

2,呃之间差别不大?编辑模型在属性上有一个额外字段(ID)和一些属性.现在,如果我们要像这样结合2:

    public class DisplayPersonViewModel
    {
        [Required]
        [StringLength(20)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(20)]
        public string LastName { get; set; }

        [Required]
        public string Bio { get; set; }
    }

    public class EditPersonViewModel : DisplayPersonViewModel
    {
        [Required]
        public int ID { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

这当然更干,因为我们没有要维护的重复字段,但现在我们在显示视图模型上有无关的信息(属性).无论如何,我更倾向于第二种方法,因为我们的一些屏幕有超过25个字段!(......那是我无法控制的,所以请不要竖起来:) :)但是,我只是想听听意见,以便更好地了解可能是"最佳实践".

Dar*_*rov 4

是的,第二种方法对我来说似乎很好。除了胃部发痒的感觉告诉您到底为什么要使用验证属性装饰显示视图模型之外,不用担心。但是,如果您可以接受它,那么与复制视图模型相比,它确实是更好的选择。

不幸的是,就我个人而言,我无法忍受这种感觉,这就是为什么我使用FluentValidation.NET来定义我的验证规则而不是数据注释。它允许我将这些规则与视图模型分开,这样我就不用担心验证规则会污染所谓的显示视图模型。因此,我将以与您相同的方式定义 2 个视图模型,并从中EditPersonViewModel派生DisplayPersonViewModel,然后在单独的类中定义我的视图EditPersonViewModelValidator模型。EditPersonViewModel

哦,还有一个旁注:用[Required]属性修饰不可空类型是没有必要的。所有不可为 null 的类型都是其基本性质所必需的。所以而不是:

[Required]
public int ID { get; set; }
Run Code Online (Sandbox Code Playgroud)

你应该只拥有:

public int ID { get; set; }
Run Code Online (Sandbox Code Playgroud)