ASP.NET MVC模型验证是否违反MVC规则?

ASP.NET MVC模型验证是否违反MVC规则?,asp.net,asp.net-mvc,view,model,model-validation,Asp.net,Asp.net Mvc,View,Model,Model Validation,使用ASP.NET MVC,我有一个模型,我将属性附加到该模型,这样我就可以使用MVC模型绑定验证,但这是否打破了MVC的规则,即将属于视图的项放入模型中?我希望我不是为了聪明而来,不管我多么好奇别人的意见 public class Payments { [DataType(DataType.Text)] [DisplayFormat(NullDisplayText="")] [Display(Name="Payment Id")] [Required(Error

使用ASP.NET MVC,我有一个模型,我将属性附加到该模型,这样我就可以使用MVC模型绑定验证,但这是否打破了MVC的规则,即将属于视图的项放入模型中?我希望我不是为了聪明而来,不管我多么好奇别人的意见

public class Payments
{
    [DataType(DataType.Text)]
    [DisplayFormat(NullDisplayText="")]
    [Display(Name="Payment Id")]
    [Required(ErrorMessage="Required")]
    public int PaymentId { get; set; } //todo: make this into a dropdown

    [DataType(DataType.Text)]
    [Display(Name="Bill Name")]
    [Required(ErrorMessage = "Required")]
    public string PaymentName { get; set; }

    [DataType(DataType.Date)]
    [Display(Name="Date to Post Payment")]
    [Required(ErrorMessage = "Required")]
    public DateTime PaymentDate { get; set; }

    [DataType(DataType.Currency)]
    [Range(0, 922337203685477.5807)]
    [Required(ErrorMessage = "Required")]
    public double PaymentAmount { get; set; }
}

  • 是的。这就是为什么您应该使用ViewModels。

    您可以但不必将这些验证属性放入您的模型中

    但最好使用ViewModel:

    public class PaymentsViewModel
    {
        [DataType(DataType.Text)]
        [DisplayFormat(NullDisplayText="")]
        [Display(Name="Payment Id")]
        [Required(ErrorMessage="Required")]
        public int PaymentId { get; set; } //todo: make this into a dropdown
    
        [DataType(DataType.Text)]
        [Display(Name="Bill Name")]
        [Required(ErrorMessage = "Required")]
        public string PaymentName { get; set; }
    
        [DataType(DataType.Date)]
        [Display(Name="Date to Post Payment")]
        [Required(ErrorMessage = "Required")]
        public DateTime PaymentDate { get; set; }
    
        [DataType(DataType.Currency)]
        [Range(0, 922337203685477.5807)]
        [Required(ErrorMessage = "Required")]
        public double PaymentAmount { get; set; }
    }
    
    在您看来,而不是:

    @model YourProject.Models.Payments
    
    您使用:

    @model YourProject.Models.PaymentsViewModel
    

    用于验证。

    严格意义上它是否违反了MVC,是的,很可能。有没有违反这一点没有害处的时候?当然但是,有一些机制可以帮助您解决问题,并将关注点分开

    您可以在视图中使用持久化的域对象并对其进行验证,但当视图开始变得复杂时,视图模型就成为一种必要。对于死气沉沉的简单域模型或仅视图视图(而不是编辑/创建),我有时会做一些修改,并将它们作为复合对象的一部分发送到视图中:

    class MyViewModel
    {
        public MyDomainModel DomainObj;
        public int OtherViewInfo;
    }
    
    但是,对于创建和编辑场景,ViewModels要好得多。它们允许您完全控制发送到视图和从视图发送的数据

    如果您使用的是EF 4.1和CodeFirst,那么是的,您将在域和ViewModel之间复制一些属性和属性。这是不可避免的,但它为您提供了针对视图执行不同验证的灵活性

    我发现在实际保存域对象时,在控制器中增加一层保护非常有用,以防我在视图中错过了一些验证:

    public class MyController : Controller
    {
        [HttpPost]
        public ActionResult Edit(int id, MyViewModel model)
        {
            try
            {
                ...Do stuff, check ModelState.IsValid...
                _context.SaveChanges()
            }
            catch (DbEntityValidationException dbEx)
            {
                // Catch any validation errors on the domain that weren't duplicated
                // in the viewmodel
                ModelState.AddModelError("Form", dbEx);
            }
    
            return View(model);
        }
    }
    

    下一个问题是如何在域模型和视图模型之间映射。有很多策略和工具(是的,拼写错误)。就个人而言,我一直在使用ValueInjector,不过如果您设置了映射层,您可以同时尝试这两种方法。我发现这两种方法在100%的情况下都不起作用,或者至少我可以知道如何做我需要的事情,但是映射服务使定义自定义的从左到右映射变得很容易。

    将ViewModel类放在哪里最合适?假设您有两个解决方案:MyProject.UI和MyProject.Models,付款类是MyProjects.Models.Payment。将ViewModel放在MyProject.UI.Models.PaymentViewModel或MyProject.Models.PaymentViewModel中更好吗?@WeekendWarrior:实际上放在哪里并不重要。我有一个习惯做两个文件夹:模型和视图模型,并把它们放在那里。你的模型看起来像什么?这里看起来更像是语义参数,尽管这是一个简单的例子。老实说,所谓的ViewModel是精确的模型,可以从实体中构建。但是实体/表格记录!=ModelI不理解MVC上下文中的“ViewModel”一词。我理解“MVC”对模型视图控制器的作用。我理解“MVVM”代表模型视图模型。那么,如果我们谈论的是MVC,那么为什么要谈论ViewModels呢?是的,这个答案是不正确的,并且违反了MVC。。。模型!=实体重要的是,根据手边的技术堆栈上下文进行定制回答和讨论。在讨论ASP.NET MVC时,模型和ViewModels是有意义的,而在阅读Martin Fowler时,则没有意义。MVC的最初概念几乎与几乎所有语言在web上使用的实际实现完全不同。