最近,在将我们的项目从 .NET 6 迁移到 .NET 8 时,我的队友 Jeremy Chan 发现了模型绑定行为中的一个未记录的更改,该更改似乎自 .NET 7 以来就出现了。此更改在官方 .NET 中没有明确解释文档,因此开发人员很容易忽略它。
为了说明这个问题,让我们从一个简单的 Web API 项目开始,探索一个突出显示更改的简单控制器方法。
[ApiController] public class FooController { [HttpGet()] public async void Get([FromQuery] string value = "Hello") { Console.WriteLine($"Value is {value}"); return new JsonResult() { StatusCode = StatusCodes.Status200OK }; } }
然后我们假设我们在 .NET 6 和 .NET 8 项目中都启用了 nullable。
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <Nullable>enable</Nullable> ... </PropertyGroup> ... </Project>
在 .NET 6 中,当我们使用 /foo?value= 调用端点时,我们将收到以下错误。
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-5bc66c755994b2bba7c9d2337c1e5bc4-e116fa61d942199b-00", "errors": { "value": [ "The value field is required." ] } }
但是,如果我们将方法改成如下,就不会出现这个错误了。
public async void Get([FromQuery] string? value) { if (value is null) Console.WriteLine($"Value is null!!!"); else Console.WriteLine($"Value is {value}"); return new JsonResult() { StatusCode = StatusCodes.Status200OK }; }
使用 /foo?value= 调用端点时的日志将是“Value is null!!!”。
因此,我们可以知道没有值的查询字符串将被解释为空。这就是为什么当值不可为空时会出现验证错误的原因。
因此,我们可以说,为了使端点在.NET 6中工作,我们需要将其更改为如下以使该值可选。这不会将值标记为必填字段。
public async void Get([FromQuery] string? value = "Hello")
现在,如果我们使用 /foo?value= 调用端点,我们将收到打印的日志“Value is Hello”。
那么在 .NET 8 中如何使用相同的原始设置,即如下所示。
public async void Get([FromQuery] string value = "Hello")
在.NET 8中,当我们使用 /foo?value= 调用端点时,我们将看到打印日志“Value is Hello”。
那么,这里发生了什么?
.NET 7 中引入了新的接口 IParsable。因此,从 .NET 7 开始,IParsable.TryParse API 用于绑定控制器操作参数值。
初步研究表明,从 .NET 7 开始,使用新的模型绑定实现会导致这种情况发生。
KOSD,或 Kopi-O Siew Dai,是我喜欢的一种新加坡咖啡。它基本上是一杯加了一点糖的咖啡。这个系列的目的是记录我在喝一小杯 Kopi-O Siew Dai 时获得的技术知识。
以上是[KOSD] .NET o .NET8 中 FromQuery 模型绑定的更改的详细内容。更多信息请关注PHP中文网其他相关文章!