6

使用 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; }
}
4

3 回答 3

10

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

于 2011-05-18T14:10:28.827 回答
10

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

但最好使用 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

进行验证。

于 2011-05-18T14:19:05.643 回答
1

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

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

class MyViewModel
{
    public MyDomainModel DomainObj;
    public int OtherViewInfo;
}

但是,对于创建和编辑场景,ViewModel 要好得多。它们允许您完全控制发送到视图和视图发送的数据。

如果您使用的是 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);
    }
}

下一个要问的问题是如何在域模型和 ViewModel 之间进行映射。有许多策略和工具 - AutoMapperValueInjecter(是的,拼写错误)。就个人而言,我一直在使用 ValueInjecter,但如果你设置了一个映射层,你可以尝试两者。我发现两者都不会在 100% 的情况下工作,或者至少我可以弄清楚如何做我需要的事情,但是地图服务可以轻松定义自定义的从左到右的地图。

于 2011-05-18T14:38:06.813 回答