验证注释-实体框架核心

时间:2020-01-29 07:43:19

标签: .net-core entity-framework-core data-annotations

我有一个模型,该模型从cshtml视图发布到我的后端。该模型也是数据库表的表示。

此代码如下所示查找HTTP POST:

[HttpPost]
public IActionResult CreateAKG(Conversation akg)
{
    if (ModelState.IsValid && ValideD3OrD4Values(akg))
    {
        akg.RDPflichfelderBefuellt = true;
    }
    else
    {
        akg.RDPflichfelderBefuellt = false;
    }
    if (akg.Kommentare == null)
    {
        akg.Kommentare = new List<Kommentar>();
    }
    if (akg.AuftragsklaerungsgespraechId == 0)
    {
        this.MyDatabase.Conversation.Add(akg);
    }
    else
    {
        this.MyDatabase.Conversation.Update(akg);
    }
    this.MyDatabase.SaveChanges();
    return RedirectToAction("Index");
}

表示模型的类称为“对话”。有一些由验证注释注释的属性。注释只能由Controller / ModelState.IsValid使用,而不能用于数据库表。

下面是代码示例:

public class Conversation
{
    public int ConversationId { get; set; }

    [Required(ErrorMessage = "This field is required.")]
    public DateTime? DatumAKG { get; set; }

    [MaxLength(256, ErrorMessage = "This field cannot be more than 256 characters")]
    public string KontierungFertigungskosten { get; set; }

    [MaxLength(256, ErrorMessage = "This field cannot be more than 256 characters")]
    public string KontierungQVP { get; set; }

    [MaxLength(256, ErrorMessage = "This field cannot be more than 256 characters")]
    public string KontierungLayoutkosten { get; set; }

    [MaxLength(256, ErrorMessage = "This field cannot be more than 256 characters")]
    public string KontierungBeschaffung { get; set; }
    public bool RDPflichfelderBefuellt { get; set; }
}

ModelState.IsValid仅用于验证布尔值是true还是false。不需要其他验证。

我现在的问题是,由于数据注释的原因,数据库设计中现在通常配置为NULL的字符串现在配置为NOT NULL。

如果我尝试在数据库中存储新对话,则会引发错误,某些字符串值不能为null。

我想做的是:

  1. 控制器上的验证

  2. 无验证注释会更改数据库设计

1 个答案:

答案 0 :(得分:1)

由于属性和要求不同,您应该有2个不同的对象

// this is you database object
public class Conversation {
        [MaxLength(256, ErrorMessage = "This field cannot be more than 256 characters")]
        public string KontierungQVP { get; set; }

}

// this your Data Transfer Object
public class ConversationDTO {
        [MaxLength(256, ErrorMessage = "This field cannot be more than 256 characters")]
        [Required]
        public string KontierungQVP { get; set; }
}

您的EF模型应始终代表数据库。如果要添加额外的验证或条件,则应该对另一个对象执行此操作,并在这些对象之间简单地进行传输。拥有2种不同类型的对象可为您提供更多的模块化。

编辑:

有一种方法可以解决您的问题,但这不是推荐的方法,它可能会引起问题。您要使用2个上下文,并使用FluentAPI而不是数据注释来配置必需的属性。

// Call this method in your context.
protected override void OnModelCreating(your_builder){
    modelBuilder.Entity<Conversation>()
        .Property(p => p.KontierungQVP)
        .IsRequired();
}

通常,您希望具有2个不同的上下文。一种将初始化数据库的位置。另外一个将通过FluentAPI定义所需的属性(不是数据注释)。

因此,请重述一个DbContext用于创建数据库,而另一个则用于操作。当然,这将导致差异,并且很容易忘记对数据库的验证等等。