将 JsonSchema.Net 插入 ASP.NET Core 进行验证

问题描述 投票:0回答:1

我们希望利用 JsonSchema.Net 来验证发送到 ASP.NET Core 端点(最小 API)的 json。失败结果还必须以 RFC

ProblemDetails
格式返回。这是可行的,但需要跳过一些障碍;

  1. ValidatingJsonConverter
    添加到最小 API 使用的
    JsonSerializerOptions
    转换器 (
    builder.Services.ConfigureHttpJsonOptions
    )
  2. 创建一个异常处理程序,可以根据 JsonSchema.Net 抛出的
    ProblemDetails
    构建
    JsonException
    结果
app.UseExceptionHandler(exceptionHandlerApp
    => exceptionHandlerApp.Run(async context =>
    {
        IExceptionHandlerFeature feature = context.Features.Get<IExceptionHandlerFeature>() ?? throw new Exception("Unable to get error feature");

        if (feature.Error.InnerException is JsonException e && e.Data["validation"] is EvaluationResults validationResults && validationResults.HasDetails)
        {
            Dictionary<string, string[]> errors = validationResults.Details.Where(detail => detail.HasErrors).ToDictionary(detail => detail.InstanceLocation.ToString(), detail =>
            {
                return detail.Errors!.Select(error => error.Value).ToArray();
            });

            await Results.ValidationProblem(errors).ExecuteAsync(context);
        }
    }));
  1. 手动构建架构

     public static readonly JsonSchema InvokeRequestSchema =
         new JsonSchemaBuilder()
                 .Type(SchemaValueType.Object)
                 .Required("appUserId")
                 .Properties(
                      ("appUserId", new JsonSchemaBuilder()
                          .Type(SchemaValueType.String)
                          .Format(Formats.Uuid)
                      )
                 );
    
  2. 使用

    [JsonSchema]
    属性将该模式应用到我们的 DTO

    [JsonSchema(typeof(InvokeRequest), nameof(InvokeRequestSchema))]
    public class InvokeRequest
    

这一切都有效

{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "errors": {
        "/appUserId": [
            "Value does not match format \"uuid\""
        ]
    }
}

我是否正确地说,更好的做法是提前从类型(使用例如

FromType<>(InvokeRequest)
)生成模式,将该 JSON 模式写入磁盘,然后在应用程序启动时将其解析回以用于验证?

asp.net-core jsonschema json-everything
1个回答
0
投票

我更喜欢硬编码版本。 它是静态的,并且以推断意图的方式非常明确地定义模型。 其次,您可以微调手动构建的架构(无论是使用构建器硬编码还是以 JSON/YAML 手写)。 这一代人可能并不总能得到你想要的一切。

也就是说,当您更改模型时,硬编码方法不会更新。 拥有一个从模型生成并保存为外部文件的构建过程可能很有价值。 这实际上取决于您想要什么以及什么对您来说更容易。

如果生成的模式足以满足您的需求,那么我会走这条路。 我还会使用某种定期手动检查或验证测试(例如使用Verify之类的东西)来确保这一代正在按照您的预期进行。


此外,关于您返回的错误,请阅读我的博客文章解释 JSON 架构输出。 试图找出哪些错误与故障相关或对用户有用可能很棘手。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.