ASP.NET Core WebAPI FromBody 属性未验证对象非引用字段
Posted
技术标签:
【中文标题】ASP.NET Core WebAPI FromBody 属性未验证对象非引用字段【英文标题】:ASP.NET Core WebAPI FromBody attribute is not validating object non-reference fields 【发布时间】:2020-11-07 15:39:40 【问题描述】:我在我的控制器中创建了动作:
[HttpPost]
public async Task<IActionResult> Create([FromBody] PostCreate createDto)
// do something with Create DTO
它接受 DTO 来创建 Post(参数标有 [FromBody] 属性)。该 DTO 有 2 个属性:字符串(引用类型)内容属性和 System.Guid(值类型)属性:
public class PostCreate
[Required(ErrorMessage = "content is required")]
public string Content get; set;
[Required(ErrorMessage = "blog id is required")]
public Guid BlogId get; set;
问题是,当我发送有效对象时,一切正常(Content 和 BlodId 属性都已初始化)。但是当我发送空对象时,它只检查 Content 属性:
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|dfcd1687-4a0b9320d8411509.",
"errors":
"Content": [
"content is required"
]
如果我只为 Content 属性提供值,它将通过验证,并且 BlogId 值为“00000000-0000-0000-0000-000000000000”或 Guid.Empty。所有非引用类型都是一样的(例如 int 值为 0)。
问题 1:“为什么会这样?” 问题2:“如何使默认验证检查非引用类型为空?”
更新(有用的解决方法):
正如Octavio Armenta 在answer 中指出的那样:“您可能必须创建一个自定义属性来检查Guid 的空性。如果您想使用一个属性。”。我是这样做的:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class NotEmptyAttribute : ValidationAttribute
public const string DefaultErrorMessage = "The 0 field must not be empty";
public NotEmptyAttribute()
: base(DefaultErrorMessage)
public override bool IsValid(object value)
if (value == null)
return true;
return value switch
Guid guid => guid != Guid.Empty,
// other non-reference types checks
_ => true
;
注意:上面的代码 sn-p 使用了一个 switch expression,这个 switch expression 只在 C# 8 之后才可用。你也可以使用一个普通的 switch statement。
【问题讨论】:
【参考方案1】:Guid 的默认值为Guid.Empty
,它通过了RequiredAttribute
的验证。您可能必须创建一个自定义属性来检查 Guid 是否为空。如果你想使用一个属性。
【讨论】:
您也可以按照@Eugene 的建议进行操作并更改为可为空的类型。 抱歉耽搁了。由于我的英语知识平庸,我没有立即明白你在说什么。我遇到了一个类似的解决方案并决定更新这个问题,之后我注意到你在谈论这样一个解决方案。谢谢你的回答。【参考方案2】:值类型的属性使用值类型的默认值进行初始化。如果您将不可为空的类型更改为可空的类型(即 Guid
到 Guid?
),您的验证应该按预期工作:
public class PostCreate
[Required(ErrorMessage = "content is required")]
public string Content get; set;
[Required(ErrorMessage = "blog id is required")]
public Guid? BlogId get; set;
Content
已按预期进行验证,因为字符串的默认值为 null
【讨论】:
以上是关于ASP.NET Core WebAPI FromBody 属性未验证对象非引用字段的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core 2.2 WebAPI 405 方法不允许
带你做 WebAPI 迁移 ASP.NET Core 2.0