【问题标题】:Validation Annotation - Entity Framework Core验证注解 - 实体框架核心
【发布时间】:2020-01-29 07:43:19
【问题描述】:

我有一个模型从 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");
}

代表模型的类称为Conversation。有一些属性由 Validation Annotations 注释。注解只能由 Controller / ModelState.IsValid 使用,不能用于 Database-Table。

这是代码示例:

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 仅用于验证布尔值是真还是假。不需要其他验证。

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

如果我尝试在数据库中存储一个新对话,则会抛出一些字符串值不能为空的错误。

我想做的是:

  1. 控制器验证

  2. 没有更改数据库设计的验证注释

【问题讨论】:

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


    【解决方案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 用于您的数据库创建和另一个用于您的操作。当然这会导致差异,并且很容易忘记对数据库的验证等等。

    【讨论】:

    • 是否无法激活或停用验证?我只需要在 http post 中进行验证 - 在数据库中不应该有任何验证
    • 我稍微改变了问题 - 也许有可能。感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    相关资源
    最近更新 更多