.NET 5.0 Web API 不适用于具有所需属性的记录

问题描述

我使用 C# 9.0 record 类型作为 .NET 5.0 Web API 项目的绑定模型。某些属性是必需的。

我正在使用 record 位置语法,但收到错误。

public record Mail(
    System.Guid? Id,[property: Required]
    string From,[property: Required]
    string[] Tos,[property: Required]
    string Subject,string[]? Ccs,string[]? Bccs,[property: Required]
    Content[] Contents,Attachment[]? Attachments
);

然后将其公开为我的 Index 操作的绑定模型:

public async Task<ActionResult> Index(Service.Models.Mail mailRequest)
{
    …
}

然而,每当我尝试提出请求时,我都会收到以下错误:

记录类型“Service.Models.Mail”在属性“Contents”上定义了验证元数据,将被忽略。 “Contents”是记录主构造函数中的一个参数,验证元数据必须与构造函数参数相关联。

我尝试删除 Contents 属性上的属性,但随后在下一个(先前)属性上失败。我尝试使用 [param: …] 代替 [property: …],并将它们混合使用,但一直出现相同类型的错误。

我环顾了整个网络,并没有发现任何针对 C# 9 记录以不同方式处理注释的建议。我已尽力而为,但除了将我的记录转换为 POCO 之外,我没有任何想法。

解决方法

我放弃了使用 Positional 构造函数,并且使用详细的属性完整声明,它可以工作。

public record Mail
{
    public System.Guid? Id { get; init; }

    [Required]
    public string From { get; init; }

    [Required]
    public string[] Tos { get; init; }

    [Required]
    public string Subject { get; init; }

    public string[]? Ccs { get; init; }

    public string[]? Bccs { get; init; }

    [Required]
    public Content[] Contents { get; init; }

    public Attachment[]? Attachments { get; init; }

    public Status? Status { get; init; }

    public Mail(Guid? id,string @from,string[] tos,string subject,string[]? ccs,string[]? bccs,Content[] contents,Attachment[]? attachments,Status status)
    {
        Id = id;
        From = @from;
        Tos = tos;
        Subject = subject;
        Ccs = ccs;
        Bccs = bccs;
        Contents = contents;
        Attachments = attachments;
        Status = status;
    }
}
,

我在 ASP.NET Core Razor 页面上发现了类似的东西:

InvalidOperationException:记录类型“WebApplication1.Pages.LoginModelNRTB+InputModel”在属性“PasswordB”上定义了验证元数据,将被忽略。 “PasswordB”是记录主构造函数中的一个参数,验证元数据必须与构造函数参数相关联。

来自

Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata.ThrowIfRecordTypeHasValidationOnProperties()

经过一番挖掘,我发现:https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs

所以也许正如您所做的那样,详细声明是前进的方向。

Positional record attributes in ASP.NET Core 背景

How do I target attributes for a record class? 更多背景

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...