ASP.NET Core 6 MVC - EF Core 6 - 模型未正确验证

rur*_*gle 5 c# npgsql entity-framework-core asp.net-core

我目前正在尝试使用 ASP.NET Core 6 MVC 和 Entity Framework Core 6 和 npgsql 启动一个新项目。

\n

当我尝试添加一个具有外国身份的实体时ModelState.IsValid不断返回 false - 因为模型不会扩展外国实体。

\n

基本上我遵循了官方文档:

\n\n

所以我的课程看起来像:

\n
namespace PV.Models\n{\n    public class Fakultaet\n    {\n        [Key]\n        public int FakultaetID { get; set; }\n        [Required]\n        public string FakuName { get; set; }\n    }\n\n    public class Studiengang\n    {\n        [Key]\n        public int StudiengangID { get; set; }\n        [Required]\n        public string StudiengangName { get; set;}\n        [Required,ForeignKey("Fakultaet")]\n        public int FakultaetID { get; set; }\n        \n        public Fakultaet Fakultaet { get; set; }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

部分视图:

\n
@model PV.Models.Studiengang\n<tr>\n         <td>\n            <div asp-validation-summary="ModelOnly" class="text-danger"></div>\n            <input asp-for="StudiengangName" class="form-control" />\n            <span asp-validation-for="StudiengangName" class="text-danger"></span>\n        </td>\n        <td>\n            <select asp-for="FakultaetID" class="form-control" asp-items="ViewBag.FakultaetId">\n                <option disabled="disabled" selected="selected" value="0">Bitte w\xc3\xa4hlen...</option>\n            </select>\n            <span asp-validation-for="FakultaetID" class="text-danger"></span>\n        </td>\n        <td>\n            <input type="submit" value="Speichern" class="btn btn-outline-success btn-sm" id="btn-addinline-submit" />\n            <input type="reset" onClick="location.reload()" class="btn btn-outline-danger btn-sm" id="btn-addinline-abort" value="Abbrechen" />\n        </td>\n</tr>\n
Run Code Online (Sandbox Code Playgroud)\n

控制器:

\n
namespace PV.Controllers\n{\n    public class StudiengangController : Controller\n    {\n        private readonly PraktikumsKontext _context;\n\n        public StudiengangController(PraktikumsKontext ctx)\n        {\n            _context = ctx;\n        }\n       \n        // --- snip ---\n\n        // GET: Student/Add\n        public IActionResult AddStudiengangInline()\n        {\n            ViewBag.FakultaetId = new SelectList(_context.Fakultaeten.AsNoTracking(), "FakultaetID", "FakuName");\n            return PartialView();\n        }\n\n        // POST: Student/Add\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> AddStudiengangInline([Bind("StudiengangName, FakultaetID")] Studiengang studiengang )\n        {\n            if (ModelState.IsValid)\n            {\n                _context.Add(studiengang);\n                await _context.SaveChangesAsync();\n                return RedirectToAction("Index");\n            }\n\n            ViewData["FakultaetId"] = new SelectList(_context.Fakultaeten, "FakultaetID", "FakuName", studiengang.FakultaetID);\n\n            return PartialView(studiengang);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当我现在填写表格并发布StudiengangName=Test1234;FakultaetID=1(使用现有FakultaetID = 1时,我的模型确实如下所示:

\n
StudiengangID = 0\nStudiengangName = "Test1234"\nFakultaet = null\nFakultaetID = 1\n
Run Code Online (Sandbox Code Playgroud)\n

因此ModelState.IsValid返回false原样Fakultaetnull

\n

在这里,我假设 EF Core 6 发挥了它的魔力并解析了我引用的实体。

\n

如果我在检查模型是否有效之前添加以下代码片段,那么一切似乎都有效:

\n
StudiengangID = 0\nStudiengangName = "Test1234"\nFakultaet = null\nFakultaetID = 1\n
Run Code Online (Sandbox Code Playgroud)\n

但这似乎是一个肮脏的解决方法,因为在具有几乎相同设置的 .NET Core 3.1 中没有必要。

\n

有人知道我缺少什么吗?

\n

Ren*_*ena 7

正如这份文件所说:

从 .NET 6 开始,新项目 <Nullable>enable</Nullable>在项目文件中包含该元素。一旦启用该功能,现有的引用变量声明将变为 不可为空的引用类型

在 .NET 6 中,必须要求不可为 null 的属性,否则 ModelState 将无效。

为了达到您的要求,您可以<Nullable>enable</Nullable>从项目文件中删除。

第二种方法,您可以像下面这样初始化模型:

public class Studiengang
{
    [Key]
    public int StudiengangID { get; set; }
    [Required]
    public string StudiengangName { get; set;}
    [Required,ForeignKey("Fakultaet")]
    public int FakultaetID { get; set; }
    
    public Fakultaet Fakultaet { get; set; } = new Fakultaet();
}
Run Code Online (Sandbox Code Playgroud)

第三种方法,您可以添加?允许可为空:

public class Studiengang
{
    [Key]
    public int StudiengangID { get; set; }
    [Required]
    public string StudiengangName { get; set;}
    [Required,ForeignKey("Fakultaet")]
    public int FakultaetID { get; set; }
    
    public Fakultaet? Fakultaet { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

最后一种方法就像您在模型验证中删除密钥所做的那样。