.NET 10 Minimal API验证在DTO包含JsonElement成员时抛出“Property 'this[]' not found on type 'JsonElement'”

后端开发 2026-07-08

在.NET 10(SDK 10.0.300)上,启用Minimal API验证管道并使用 AddValidation() 时,当请求的DTO包含一个 System.Text.Json.JsonElement 成员时,会在请求阶段抛出一个 InvalidOperationException。请求永远不会到达端点。

最小重现:

using System.ComponentModel.DataAnnotations;
using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddValidation();

var app = builder.Build();
app.MapPost("/test", (MyRequest request) => Results.Ok());
app.Run();

public class MyRequest
{
    [Required]
    [MaxLength(10)]
    public string Name { get; set; } = default!;

    public JsonElement Payload { get; set; }
}

.csproj 文件:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
</Project>

请求:

POST /test
Content-Type: application/json

{ "name": "test", "payload": { "foo": "bar" } }

结果 — HTTP 500,完整异常和堆栈跟踪:

System.InvalidOperationException: Property 'this[]' not found on type 'JsonElement'.
at Microsoft.Extensions.Validation.ValidatablePropertyInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateMembersAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.Extensions.Validation.ValidatablePropertyInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateMembersAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.Extensions.Validation.ValidatableParameterInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Validation.ValidationEndpointFilterFactory.<>c__DisplayClass1_0.d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Http.RequestDelegateFactory.g__ExecuteAwaited|130_0(ValueTask1 valueTask, HttpContext httpContext, JsonTypeInfo1 jsonTypeInfo)
at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.d.MoveNext()

观察要点:

  • 管道会像将 ValidatableTypeInfo.ValidateMembersAsync 视作可验证模型一样递归进入 JsonElement,并在解析它所命名的成员 this[] 时失败
  • 它在生成验证结果之前就崩溃了,因此一个真正违反 [MaxLength(10)] 的请求也会返回500,而不是返回400
  • 移除 JsonElement 成员,或不调用 AddValidation(),可以避免崩溃

关于 JsonElement 的设计:

  • Payload 故意是一个不透明的JSON文档——它的形状由运行时的JSON架构定义,而不是由固定的C#类型决定,因此不适用POCO(重点在于接受并对任意文档进行模式验证)。
  • JsonElement 是保存任意JSON的典型 System.Text.Json 类型,这也是它被放在DTO中的原因。

这个问题不是关于是否应该以不同的方式建模——而是验证管道在 JsonElement 上崩溃,而不是跳过或优雅地报错。

问题:在DTO包含 JsonElement 时,这是否是.NET 10验证管道的已知限制/错误?是否有受支持的方式在验证遍历中排除特定成员(或类型)?

解决方案

这似乎是一个已知问题——请参阅 Validations in minimal APIs fails on several types from System.Text.Json @github,根据 fix @github 的链接,这个问题应该会在即将发布的版本中得到修复。

现在你可以尝试通过使用另一种类型来修复它,例如 JsonNode

public class MyRequest
{
    [Required]
    [MaxLength(10)]
    public string Name { get; set; } = default!;

    public JsonNode Payload { get; set; }
}

对我来说有效(在10.0.201和 10.0.300上测试通过):

enter image description here

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章