【发布时间】: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。
【问题讨论】:
标签: c# rest asp.net-web-api