Asp.net mvc 3 每个页面都有一个“ViewModel”(`Create.cshtml`和`Edit.cshtml`)? 问题

Asp.net mvc 3 每个页面都有一个“ViewModel”(`Create.cshtml`和`Edit.cshtml`)? 问题,asp.net-mvc-3,viewmodel,fluentvalidation,Asp.net Mvc 3,Viewmodel,Fluentvalidation,实际上有两个相关的问题: 我应该为每个页面创建ViewModel吗 如果在为两个页面(Create.cshtml和Edit.cshtml)创建单个ViewModel类时没有问题,我如何以不同的方式验证ViewModel(取决于正在使用的页面) 来源 视图模型 public class ProjectViewModel { public string Name { get; set; } public string Url { get; set; } public stri

实际上有两个相关的问题:

  • 我应该为每个页面创建ViewModel吗
  • 如果在为两个页面(
    Create.cshtml
    Edit.cshtml
    )创建单个ViewModel类时没有问题,我如何以不同的方式验证ViewModel(取决于正在使用的页面)
  • 来源 视图模型

    public class ProjectViewModel
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public string Description { get; set; }
    }
    
    @using BindSolution.ViewModel.Project
    @model ProjectViewModel
    @{
        ViewBag.Title = Model.Name;
    }
    
    @Html.EditorForModel()
    
    @using BindSolution.ViewModel.Project
    @model ProjectViewModel
    @{
        ViewBag.Title = "New Project";
    }
    
    @Html.EditorForModel()
    
    Edit.cshtml

    public class ProjectViewModel
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public string Description { get; set; }
    }
    
    @using BindSolution.ViewModel.Project
    @model ProjectViewModel
    @{
        ViewBag.Title = Model.Name;
    }
    
    @Html.EditorForModel()
    
    @using BindSolution.ViewModel.Project
    @model ProjectViewModel
    @{
        ViewBag.Title = "New Project";
    }
    
    @Html.EditorForModel()
    
    Create.cshtml

    public class ProjectViewModel
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public string Description { get; set; }
    }
    
    @using BindSolution.ViewModel.Project
    @model ProjectViewModel
    @{
        ViewBag.Title = Model.Name;
    }
    
    @Html.EditorForModel()
    
    @using BindSolution.ViewModel.Project
    @model ProjectViewModel
    @{
        ViewBag.Title = "New Project";
    }
    
    @Html.EditorForModel()
    
    ProjectValidator.cs

    public class ProjectValidator : AbstractValidator<ProjectViewModel>
    {
        private readonly IProjectService _projectService;
    
        public ProjectValidator(IProjectService projectService)
        {
            _projectService = projectService;
    
            RuleFor(p => p.Name)
               .NotEmpty().WithMessage("required field")
    
               /*The validation should be made only if the page is Create.cshtml. That is, if you are creating a new project.*/
               .When(p => p.??) //Problem Here!!
    
               .Must(n => !_projectService.Exist(n)).WithMessage("name already exists");
    
            RuleFor(p => p.Url)
                .NotEmpty().WithMessage("required field");
        }
    }
    
    笔记 如果我为每个页面创建一个ViewModel,那么会有重复的代码,因为页面具有相同的属性

    在ViewModel上添加一个属性,指示显示的页面并不能解决实例化ViewModel的问题,我使用AutoMapper

    为了验证数据,我使用


    谢谢大家的帮助

    我的理解是,视图模型和视图之间没有1:1的相关性。通常情况下,您将拥有一个不需要ViewModel的视图


    当且仅当您需要一个完全平行并针对特定视图定制的模型时,才需要创建ViewModel。这不会是100%的情况。

    当功能/用例/验证在使用不同模型的页面之间不同时。如果它除了存在ID或类似的东西之外完全相同,我使用相同的模型,如果差异非常小,也可以使用相同的视图


    由于您的验证是不同的,如果我进行验证,我将创建两个不同的模型,以便使用开箱即用的DataAnnotations,尽管您可能不需要验证。您也可以在编辑模型上为name设置只读属性,因为它不再可编辑。

    对于我来说,相同的对象每次都必须具有相同的验证,主要是为了确保对象的一致性,如果它是创建或编辑的,则必须独立进行验证


    我认为您应该只创建一个验证,并编辑您的“exists”方法以通过验证它是新对象还是存储库中的当前对象。

    就我个人而言,我对两个视图模型没有问题,特别是如果(正如Paul Tyng所建议的)您对编辑和创建场景常用的字段使用基类

    但是,如果确实只需要一个视图模型,则需要:

    • 向视图模型添加标志,并在验证器中使用When()方法。但请注意,这不会生成适当的仅客户端验证
    • 定义第二个验证器并从控制器调用相应的验证器(即,代替“自动”验证)

    Charles,验证用于编辑和创建。使用职责分离的概念,我创建了一个负责验证ViewModel的类。问题是,如何使用相同的验证,但如果是新记录,则忽略某些规则。(如上面代码所列)我不明白他的意思。我有一个用于编辑.cshtml和创建.cshtml的视图模型,还有一个用于验证该视图模型的类。我的问题是,如果用户正在编辑项目,如何忽略规则。关于为每个页面创建一个ViewModel,我觉得不太舒服,那就是复制代码。如果代码在两个地方都做相同的事情,那么它只会复制代码,而事实并非如此。你可以使用一个基本模型类来实现共享功能。我完全同意!第二个问题呢?如果用户在my
    ProjectValidator
    类中编辑项目,如何忽略该规则