带有EF Core 3的ASP.NET Core 3远程验证

问题描述 投票:0回答:2

确实是EF初学者的问题的一部分,但是我使用ASP.NET MVC Core 3和EF Core 3进行[远程]验证时遇到了问题。

[根据Microsoft的一篇帖子,它建议将所有内容保持为“干燥”(不要重复自己)。因此,按照指示,我将用于验证的数据注释添加到“实体”类(在我的上下文中为DbSet)。将Presentation逻辑与我的DB逻辑混合在一起,这感觉有点奇怪,但是我也喜欢只写一次,所以我想尝试一下。

关于我的实体。它与另一个实体具有多对多关系。因此,假设我的实体是“人”,那么,此人可以拥有一列汽车。

我的创建方法

过去,使用MVC时,我总是编写“视图模型”以仅包含视图中数据绑定所需的内容。但是,要保持事物干燥,我显然需要使用Person实体类在View中进行绑定,因为这是我的DataAnnotations所在的地方。它还有其他各种属性,不需要用户填写,所以我想我不必在UI上公开它们(尽管我知道这不会阻止黑客向我提供这些信息。 。但这是另一个主题。)

对于创建简单的输入框,这很完美,但是我需要向用户显示要选择的汽车列表。那么,由于它不在我的实体上,我从哪里可以得到可用汽车的列表?我通过创建一个类似于以下包装的ViewModel类来解决此问题:

public class MyViewModel
{
    public Person Entity {get; set;}
    public List<Car> Cars {get;set;}
}

现在,我必须将数据绑定到我称为“实体”的属性,并且可以从其他属性中提取其他汽车数据。

这也很好。但是,当我进行验证时,便遇到了问题。

因此,我的Person类具有以下(make-believe)属性

public class Person
{
    [Remote("CheckIdIsAvailable","Persons")]
    public string Id { get; set; }
}

因此,请记住我的Person实例是ViewModel的Entity属性,因此View具有以下形式:

<tr>
    <td>ID</td>
    <td><input asp-for="Entity.Id" /></td>
    <td><span asp-validation-for="Entity.Id" class="text-danger"></span></td>
</tr>

在我的控制器中,我具有验证方法:

[HttpGet]
public async Task<IActionResult> CheckIdIsAvailable(string Id)
{
    ....
}

但是,该值变为“ null”,因为通过电线发送的参数为“ ...?Entity.Id = ABCD”,而我的字符串称为'Id',而不是'Entity.Id'。

所以,我要么在这里遗漏了一些明显的东西,要么以错误的方式进行此操作。

asp.net-mvc entity-framework asp.net-core-mvc entity-framework-core data-annotations
2个回答
1
投票

您可以在远程验证操作中的对象中仅接收Entity.Id

[HttpGet]
 public async Task<IActionResult> CheckIdIsAvailable(Person entity)
{
  string Id = entity.Id;
  //other logic
}

对于模型绑定,参数的名称为entity


1
投票

正如克里斯·普拉特(Chris Pratt)所说的那样,您应该使用ViewModel对象与视图进行绑定是正确的。

值得看看标记帮助器为您生成的HTML,并注意到输入将具有name属性,该属性具有您在该对象(asp-for=""部分)中链接到的任何属性。 name属性是从视图到控制器的model binding如何知道如何映射从视图返回的对象。

但是理想情况下,您将在填充ViewModel对象后将其发送到视图,并期望向后返回并映射到任一侧的实体,而无需将实体暴露/暴露给外界。

public async Task<IActionResult> CheckIdIsAvailable(PersonViewModel model)
{

}

然后您将验证添加到ViewModel属性而不是您的Entity。

您应该在Entity类中真正拥有的唯一属性是,如果您使用的是Code First,并且正在定义数据库中的字段-像字符串字段的[MaxLength()]属性(这是一个好习惯,因为通过默认情况下,如果您不定义字符串字段,我认为EF会将其设置为NVARCHAR(MAX),这对于以后的查找来说不是很好。但这不重要。

除了属性以外,还有其他定义字段属性的方法也可以导致“更干净”的实体定义,但这在这里并不是真正的问题。

© www.soinside.com 2019 - 2024. All rights reserved.