根据需要验证正文中的不可为空属性 - AspNetCore 3.1 [英] Validating non-nullable property in Body as Required - AspNetCore 3.1

查看:43
本文介绍了根据需要验证正文中的不可为空属性 - AspNetCore 3.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试验证是否在 ModelState 无效且 BadRequest 被发送回客户端的请求中完全忽略了属性/字段,但是我正在努力处理请求正文中的不可为空类型.

I am trying to validate that if a property / field is completely left off on a request that the ModelState is invalid and a BadRequest is sent back to the client, however I am struggling with handling of non-nullable types in request bodies.

[Required] public string NullableString { get; set; }

适用于不可为空和可为空的参数

public IActionResult RequiredNonNullableIntQueryString([Required]int nonNullableInt)

public IActionResult RequiredNullableStringQueryString([Required]string nullableString)

但是,它不适用于请求正文中的不可为空类型

 public IActionResult RequiredNonNullableIntBody([FromBody]NonNullablesRequest request)

 public class NonNullablesRequest
 {
    [Required] // I have also tried [BindRequired] with the same result.
    public int NonNullableInt { get; set; }
 }

我已阅读:

Microsoft 文档指出:

The Microsoft documentation states:

.NET Core 3.0 及更高版本中的验证系统将不可为 null 的参数或绑定属性视为具有 [Required] 特性.值类型,如小数和整数是不可为空的.

The validation system in .NET Core 3.0 and later treats non-nullable parameters or bound properties as if they had a [Required] attribute. Value types such as decimal and int are non-nullable.

那很酷...不过后来说

That's cool... However later says

在服务器上,如果属性为空,则认为缺少必需的值.不可为空的字段始终有效,并且永远不会显示 [Required] 属性的错误消息.

On the server, a required value is considered missing if the property is null. A non-nullable field is always valid, and the [Required] attribute's error message is never displayed.

为什么?这似乎真的没有道理.为什么要确保所有非空值都是必需的,但如果没有提供它们,则忽略错误?

Why? This really doesn't seem to make sense. Why make sure all non-nullables are required but then ignore errors if they were not supplied?

我知道很多建议表明可以执行以下的hacky解决方法,即将所需参数设置为可为空.对我来说,这似乎不是一个合理的解决方案.

I know many suggestions indicating that one can do the hacky workaround of the following, whereby one sets the required parameter as nullable. To me this does not seem like a reasonable solution.

 public class NonNullablesRequest
 {
    [Required]
    public int? NonNullableInt { get; set; }
 }

这只是感觉不对.

  • 数据类型不能准确地代表请求到达的期望
  • 每次访问该属性时都必须使用 .HasValue.Value 以避免可能为空"警告.
  • 似乎是 C# 8.0 的反模式 可空引用类型(C# 参考)
  • The datatype is not accurately representing the expectations of the request arriving
  • One has to use .HasValue and .Value every time one is accessing the property to avoid "Possible Null" warnings.
  • Seems like an anti-pattern to C# 8.0's Nullable reference types (C# reference)

如果没有提供不可为空的类型,有没有办法配置 ModelBinding 以使 ModelState 无效?

Is there a way to configure the ModelBinding to invalidate the ModelState if non-nullable types are not supplied?

编辑 1:

似乎有一些争论:ASP.NET Core [Require]不可为空的类型我不确定我是否同意 Chris Pratt.并不是我们期望不提供该值.事实上恰恰相反,我想确保调用者给我值.但是我们必须对没有提供足够数据的消费者采取防御措施,因此系统应该拒绝使用 400 BadRequest 的请求.

It seems there is quite some debate: ASP.NET Core [Require] non-nullable types I am not sure I agree with Chris Pratt. It is not that we expect the value to not be supplied. In fact the opposite, I want ensure the caller gives me the value. But one has to be defensive against a consumer not supplying the adequate data and therefore the system should reject the requests with a 400 BadRequest.

由此,预期结果是 int 而不是 int?.如果未提供任何数据,则 ModelBinder 应指示 ModelState 无效.

From this then the expected result is an int not an int?. If no data was supplied the ModelBinder should indicate that the ModelState is invalid.

但是,我可以看到有两个部分的挑战:1) 反序列化,然后是 2) 模型绑定.

I can, however, see the challenge where there are two parts 1) Deserialization and then 2) ModelBinding.

推荐答案

您可以为此使用两个不同的类.

You could use two different classes for this.

一个代表您的网络应用程序发送到后端的内容,另一个代表您的域模型(例如实体模型).

One that represents what your web-application sends to the backend and another that represents your domain model (e.g. entity model).

Http 传输对象

 public class YourWebAppDto
 {
    [Required]
    public int? NonNullableInt { get; set; }
 }

领域模型对象

 public class YourDomainModelObject
 {
    public int NonNullableInt { get; set; }
 }

通过分离这两个问题,您可以在解决 Web 应用程序潜在的无效输入问题的同时保持域模型的整洁.

By separating those two concerns, you can keep your domain model clean while addressing the potential invalid input of your web application.

当然,你需要两者之间的映射.我们为此使用自动映射器.

Of course, you need a mapping between the two. We use automapper for this.

我知道,这并不能直接回答您的问题,但作为另一种看待事物的方式可能会有所帮助.

I know, this does not directly answer your question but it might help as an other way of looking at things.

干杯,迈克

这篇关于根据需要验证正文中的不可为空属性 - AspNetCore 3.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆