首页 > 解决方案 > 制作不属于实体/类的确认字段

问题描述

我有一个表单,其中包含一个字段,我希望用户输入两次以确认其中没有任何拼写错误(就像通常使用密码一样)。支持表单的类在声明中包含以下内容:

[Display(Name = "Citation Number")]
[StringLength(20)]
[Required]
public string CitationNum { get; set; }

[NotMapped]
[Display(Name = "Confirm Citation Number")]
[Compare(nameof(CitationNum), ErrorMessage = "Data entered does not match.")]
public string ConfirmCitationNum { get; set; }

这在使用表单中的数据时效果很好,我有我想要的验证,并且[NotMapped]DataAnnotation 使得字段的数据不需要驻留在数据库中。

但是,现在,我试图在表单之外操作数据,但它引发了实体验证错误,因为当我尝试保存时,检索到的实体列表中没有该字段的任何内容。我意识到我可以在保存之前在实体中设置该属性,但这让我认为可能有更好的方法来做到这一点。

有没有更好的方法在表单上创建验证字段并将数据更新作为实体处理,或者我是否只需手动将未映射的属性设置为每次我想操作时应该匹配的属性集合记录?

标签: asp.net-mvcentity-framework

解决方案


这是避免将实体传递给视图的几个原因之一。这些是不同的问题,需要解决方法以使 EF 忽略数据,但又满足视图的行为需求。视图模型应该用于从实体的 CitationNum 投影现有数据的 CitationNum 和确认的视图。

public class SomeEntity
{
   [Key]
   public int SomeEntityId { get; set; }
   public string CitationNum { get; set; }
   // ...
}

[Serializable]
public class SomeEntityViewModel
{
   public int SomeEntityId { get; internal set; }

   [Display(Name = "Citation Number")]
   [StringLength(20)]
   [Required]
   public string CitationNum { get; set; }

   [Display(Name = "Confirm Citation Number")]
   [Compare(nameof(CitationNum), ErrorMessage = "Data entered does not match.")]
   public string ConfirmCitationNum { get; set; }
}

然后在为视图准备数据时:

var viewModel = context.SomeEntities.Where(x => x.SomeEntityId == someEntityId)
    .Select(x => new SomeEntityViewModel
    {
       SomeEntityId = x.SomeEntityId,
       CitationNum = x.CitationNum,
       ConfirmCitationNum = x.CitationNum,
       // ...
    }).Single();

利用一次ProjectTo调用即可完成的 Automapper。


推荐阅读