首页 > 其他分享 >用.NET代码生成JSON Schema 验证器

用.NET代码生成JSON Schema 验证器

时间:2024-05-31 12:33:24浏览次数:30  
标签:代码生成 验证 builder schema JSON NET HasCustomValidation Schema

问题

对于验证复杂JSON数据是否合法的需求,通常的解决方式是标准JSON Schema,.Net下有对应的JSON Schema实现库。应用程序通常需要将标准JSON schema传入实现库,来做后续的数据验证。这里有一种情况,就是如果使用者不太了解标准JSON Schema格式,但又希望能在自己的service中使用其强大的功能,或者适配需要JSON Schema的其他service。

解决方案

如果不熟悉标准JSON Schema,可以用Lateapexearlyspeed.Json.Schema 实现库的 fluent schema builder模式 来创建 JSON Schema 验证器。

这种fluent schema builder用法的接口设计思路是不完全与标准json schema的格式和命名保持一致。标准JSON Schema虽然强大,但大多开发者一般更熟悉“强类型”风格,因此实现库的fluent schema builder在配置时会先“问”用户他们期望哪种JSON token类型,然后在后续链式调用时会基于当前限定的JSON token类型继续“追问”相关的验证需求。通过这种调用方式,开发者会写出更安全的验证代码,利用IDE也会有更友好的使用体验。如下:

    var b = new JsonSchemaBuilder();
    b.ObjectHasProperty("A", b => b.IsJsonString().HasMinLength(5))
    .HasProperty("B", b => b.IsJsonNumber().IsGreaterThan(1).IsLessThan(10))
    .HasProperty("C", b => b.IsJsonArray().HasMinLength(5).HasItems(b =>
    {
        b.NotJsonNull();
    }))
    .HasProperty("D", b => b.Or(
        b => b.IsJsonFalse(),
        b => b.IsJsonNumber().Equal(0),
        b => b.IsJsonObject().HasCustomValidation((JsonElement element) => element.GetProperty("Prop").ValueKind == JsonValueKind.True, 
            jsonElement => $"Cannot pass my custom validation, data is {jsonElement}")
        )
    );
    JsonValidator jsonValidator = b.BuildValidator();
    jsonValidator.Validate(...);

看起来风格是不是很熟悉,即使没接触过JSON Schema,相信也能理解上面的.Net代码。

目前 fluent schema builder 模式下支持的验证方法:

  • NotJsonNull
  • IsJsonTrue
  • IsJsonFalse
  • IsJsonBoolean
  • IsJsonNull
  • IsJsonString:
    • Equal
    • IsIn
    • HasMaxLength
    • HasMinLength
    • HasPattern
    • HasCustomValidation
    • NotMatch
    • EndsWith
  • StringEqual
  • StringHasPattern
  • IsJsonNumber:
    • Equal
    • IsIn
    • IsGreaterThan
    • IsLessThan
    • NotGreaterThan
    • NotLessThan
    • MultipleOf
    • HasCustomValidation
  • IsJsonArray:
    • SerializationEquivalent
    • HasItems
    • HasLength
    • HasMaxLength
    • HasMinLength
    • HasUniqueItems
    • HasCustomValidation
    • Contains
    • NotContains
    • Equivalent
    • HasCollection
    • Empty
    • NotEmpty
    • Single
  • ArrayHasItems
  • ArrayContains
  • IsJsonObject:
    • SerializationEquivalent
    • HasProperty
    • HasCustomValidation
    • Equivalent
    • HasNoProperty
  • ObjectHasProperty
  • Or

其中还有HasCustomValidation() overloads 重载方法可以为 JSON树中的指定节点 创建更高级的自定义验证需求。

不仅想验证JSON数据,还想用 代码Build出来的 Json验证器 来生成 JSON Schema ?

也可以的

string standardJsonSchema = jsonValidator.GetStandardJsonSchemaText();

注意:

为了支持更高级和友好的验证体验,虽然 Lateapexearlyspeed.Json.Schema 实现库在其内部实现时尽可能使用标准JSON Schema keywords, 但一些Build方法会用到“扩展”keywords,因此当你用了那些Build()生成了 JsonValidator 实例后, 将不支持调用 GetStandardJsonSchemaText(),因为扩展keywords无法放回标准JSON Schema且被其他application 所认识,如下:

var builder = new JsonSchemaBuilder();
builder.IsJsonNumber().HasCustomValidation((double _) => true, _ => "");
JsonValidator jsonValidator = builder.BuildValidator();

Assert.Throws<NotSupportedException>(() => jsonValidator.GetStandardJsonSchemaText());

牵扯到扩展keywords的Build方法有:

  • HasCustomValidation(...)
  • HasNoProperty()
  • NotContains()
  • StartsWith()
  • EndsWith()

总结

对于验证JSON数据方面的复杂需求,可以用JSON Schema解决。

对于不希望直接交互JSON Schema格式的service来说,可以用.Net下的 Lateapexearlyspeed.Json.Schema 实现库的 fluent schema builder模式,通过写代码的形式生成JSON验证器。

对于希望用强类型风格的代码生成JSON Schema的需求,也可以用 Lateapexearlyspeed.Json.Schema 实现库的 fluent schema builder模式。

Github repo: https://github.com/lateapexearlyspeed/Lateapexearlyspeed.JsonSchema, 欢迎将使用时发现的问题提到issue。

标签:代码生成,验证,builder,schema,JSON,NET,HasCustomValidation,Schema
From: https://www.cnblogs.com/dotnet-diagnostic/p/18224293

相关文章

  • 美团多场景多任务学习论文《HiNet: Novel Multi-Scenario & Multi-Task Learning with
    模型结构模型主要包含场景抽取层和任务抽取层(上图A):场景抽取层场景抽取层主要包括了场景共享专家(Scenario-sharedexpert)模块、当前场景特有专家(Scenario-specificexpert)模块以及场景感知注意力网络,通过这三部分的信息抽取,最终形成了场景层次的信息表征场景共享专家就是一......
  • QShop商城-添加新模块/页面(CodeSmith代码生成)
    QShop商城-添加新模块/页面(CodeSmith代码生成)工具准备CodeSmith当前使用的CodeSmith71,如找不到我已分享至:https://pan.baidu.com/s/1O2Tqg3gnbToAzjH0T5ETcg?pwd=2wcv下载后按照文档CodeSmith7激活教程.doc内容激活CodeSmith 代码生成下载激活后,双击TemplateEd......
  • WinForm+SQL Server+.NET开发菜鸟驿站管理系统
    完整效果请看哔哩哔哩......
  • Kubernetes ExternalName类型的服务
    1、概述在《KubernetesHeadless服务》这篇博文中对KubenertesService资源类型进行了概述并详细介绍了Headless服务,通过这篇博文我们可以知道Service一般分为3种类型:ClusterIP、NodePort、LoadBalancer,唯独对ExternalName置若罔闻,本文将详细介绍KubernetesExternalName类......
  • Cesium 中 GeoJsonDataSource 贴地不生效的问题
    Cesium中GeoJsonDataSource可以设置clampToGround为true来确保其贴地,但有时会出现不生效的情况。可能有以下几个原因:数据源不是地理坐标系(WGS84):如果数据源不是基于WGS84坐标系的,则可能无法正确地将图形贴到地球表面。确保你的数据源使用正确的坐标系。数据源中的图形高......
  • QShop商城-快速开始-Linux使用宝塔面板发布.Net6/7
    QShop商城-快速开始-Linux使用宝塔面板发布.Net6/7QShop商城-项目介绍        QShop商城,是全新推出的一款轻量级、高性能、前后端分离的多店铺电商系统,支持微信小程序,前后端源码100%开源,完美支持二次开发,让您快速搭建个性化独立商城。技术架构:.Net6/7、WebAPI、Swag......
  • JAVA开发 利用代码生成奖状pdf-中文版
    利用代码生成奖状pdf-中文版1、图片模板2、实现代码3、生成模板(pdf文件截取)1、图片模板2、实现代码importorg.apache.pdfbox.pdmodel.PDDocument;importorg.apache.pdfbox.pdmodel.PDPage;importorg.apache.pdfbox.pdmodel.PDPageContentStream;importorg......
  • 工控现场什么情况下会采用Modbus转Profinet网关
    工控现场什么情况下会采用Modbus转Profinet网关一、原因:工控现场需要将Modbus转换为Profinet协议,这是由于在工业控制领域中,不同设备之间的通信协议多样,而Modbus和Profinet分别代表着两种不同的通信协议。Modbus是一种最常见的工业通信协议,但其速度较慢,数据量有限,在一些需要快速......
  • Kubernetes StatefulSet 扩缩容与升级
    KubernetesStatefulSet扩缩容与升级StatefulSet扩容kubectlscalestsstateful-set-web--replicas=5root@k8s-master1:~#kubectlgetpods--watch-lapp=pod-nginxNAMEREADYSTATUSRESTARTSAGEstateful-set-web-01/1Runnin......
  • Kubernetes 硬盘持久化之 StorageClass
    Kubernetes硬盘持久化之StorageClassStorageClass定义StorageClass为管理员提供了描述存储"类"的方法。不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。这个类的概念在其他存储系统中有时被称为"配置文件"。每个StorageClass......