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

查看:481
本文介绍了根据需要验证主体中的不可为空的属性-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 documentation - Model Validation # [Required] validation on the server
  • Good article on [Required] and [BindRequired] in ASP.NET Core MVC

Microsoft文档指出:

The Microsoft documentation states:

.NET Core 3.0和更高版本中的验证系统将不可为空的参数或绑定属性视为具有[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

在服务器上,如果该属性为null,则认为缺少必需的值.不可为空的字段始终有效,并且永远不会显示[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?

我知道许多建议,这些建议表明可以进行以下操作,从而将所需的参数设置为可为空.在我看来,这似乎不是一个合理的解决方案.

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的
  • 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?

似乎有很多争论: 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.

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

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天全站免登陆