如何区分模型绑定错误和模型验证错误? - c#

我正在使用ASP.NET Core MVC 2.0实现REST API项目,如果模型绑定失败(因为请求在语法上错误),我想返回400状态代码;如果模型验证失败(因为原因),我想返回422状态代码该请求在语法上是正确的,但包含不可接受的值)。

例如,给定一个类似

[HttpPut("{id}")]
public async Task<IActionResult> UpdateAsync(
    [FromRoute] int id,
    [FromBody] ThingModel model)

当路由中的id参数包含非数字字符或未在请求中指定正文时,我想返回400状态代码;而当ThingModel的属性包含无效值时,我想返回422状态代码。

从我所见,IValueProviderIModelBinder实现都像验证程序一样将错误添加到请求的ModelStateDictionary中,并且没有办法在绑定和验证之间注入代码。

如何实现这种行为?

参考方案

尚未检查选项#1,但:

ModelState。ValidationState具有4个可能的值(Unvalidated,Invalid,Valid,Skipped),如果发生模型绑定错误,我会得到Unvalidated作为值
还可以考虑使用ApiBehaviorOptions(请参见示例here)自动返回新的BadRequestObjectResult(actionContext.ModelState)-因为在绑定错误且绑定值为NULL的情况下无需执行任何操作,并且在验证错误的情况下我们可能无法执行做任何事情。

ApiBehaviorOptions的快速说明:

必须使用ApiController属性(它也需要在控制器级别上具有路由属性,并且确实会改变绑定的工作方式)
具有ApiController属性的默认行为将返回BadRequestObjectResult(actionContext.ModelState),而无需任何额外的代码和配置
如果您决定滚动自己的ApiBehaviorOptions-必须在service.AddMvc之后对其进行初始化,或者需要使用:具有类似效果的services.PostConfigure(o => {})
ApiBehaviorOptions SuppressModelStateInvalidFilter必须为false,InvalidModelStateResponseFactory才能正常工作

因此,在某些情况下,自定义过滤器是更好的解决方案(更改较少)。

如何在ASP.NET Core Web应用程序中增加JSON反序列化MaxDepth限制 - c#

我们正在将ASP.NET Core 2.1与.NET Framework 4.6.2结合使用。我们有一个客户需要向我们的Web应用程序发送一个很大程度上嵌套的json结构。当他们进行此调用时,我们将输出以下日志并返回错误: 读取器的MaxDepth超过了32。路径“ super.long.path.to property”,第1行,位置42111。”我浏览了…

ASP.NET MVC 5自定义登录,无需脚手架,数据库优先 - c#

我对asp.net和mvc还是很陌生,所以我正在努力学习尽可能多的知识...为此,我从头开始编写博客网站,但是我对身份验证和授权有些困惑。由于我倾向于不真正使用任何脚手架的东西,所以我首先要使用数据库,所以不希望asp.net身份为我创建表。我对散列和加盐密码很酷,并对照数据库检查用户,我遇到的麻烦是将用户设置为登录状态并检查他们应该能够访问什么。我真的很想…

MVC C#TempData - c#

有人可以解释一下MVC中TempData的目的。我了解它的行为类似于ViewBag,但除此之外它还有什么作用。 参考方案 TempData应该是一个短暂的实例,您应该 仅在当前和后续请求中使用它!以来 TempData以这种方式工作,您需要确定下一步 要求,并且重定向到另一个视图是您唯一的时间 可以保证这一点。因此,唯一使用TempData的方案 在重定向时…

MVC持久模型 - c#

在MVC 3应用程序中,由于某些文件夹创建逻辑,我需要能够将创建视图分为2个不同部分。在第一个视图上,我有一个带有项目名称的文本框,单击下一步按钮时,我需要为该项目创建文件夹,并且我需要一种以某种方式在我的下一个视图中获取该项目名称文件夹的方法。现在,我按“下一步”,然后我松开了“项目名称”,但我无法再获得它。在互联网上,有很多地方都以相同的方式实施它,但是…

如何将POCO类传递给.NET Core配置 - c#

我正在进行.NET Core应用程序的集成测试,并且想要使用一些测试配置。我的配置是一个POCO类,该类通过appsettings.json配置,然后通过IOptions<T>使用。在我的测试中,我想使用该类的实例。这是代码: var mySettings = GetTestSettings(); // factory method return…