問題 有很多應用程式在驗證JSON數據的時候用到了JSON Schema。 在微服務架構下,有時候各個微服務由於各種歷史原因,它們所生成的數據對JSON Object屬性名的大小寫規則可能並不統一,它們需要消費的JSON數據的屬性名可能需要大小寫無關。 遺憾的是,目前的JSON Schema沒有這方 ...
問題
有很多應用程式在驗證JSON數據的時候用到了JSON Schema。
在微服務架構下,有時候各個微服務由於各種歷史原因,它們所生成的數據對JSON Object屬性名的大小寫規則可能並不統一,它們需要消費的JSON數據的屬性名可能需要大小寫無關。
遺憾的是,目前的JSON Schema沒有這方面的標準,標準中都是大小寫敏感的。在類似上述情況下,這給使用JSON Schema進行數據驗證造成了困難。
解決方案
一種 臨時解決方案 是利用JSON Schema中的patternProperties
關鍵字,寫正則表達式來表示當前屬性名是大小寫無關的。
比如你的數據是這樣的:
[
{ "Count": 1 },
{ "count": 3 }
]
那麼你可以這樣寫JSON Schema:
{
"type": "array",
"items": {
"patternProperties": {
"^[Cc]ount$": { "minimum": 1 }
}
}
}
顯然這樣的JSON Schema會比原來的更複雜。
更優雅的解決方案
想象一下.NET下的JSON library System.Text.Json
,它的反序列化器支持 屬性名大小寫無關的選項PropertyNameCaseInsensitive
,這個是用來反序列化的。
那麼,有沒有JSON Schema實現庫支持大小寫無關的擴展選項呢?在.NET下,目前 實現庫 Lateapexearlyspeed.Json.Schema
支持 屬性名大小寫無關的 JSON Schema級驗證。由於該實現庫遵循標準JSON Schema(規定屬性名只能大小寫敏感),所以這個擴展功能需要顯式配置:
/// <summary>
/// Gets or sets a value that determines whether a property's name uses a case-insensitive comparison during validation. The default value is false.
/// </summary>
/// <returns>
/// true to compare property names using case-insensitive comparison; otherwise, false.
/// </returns>
public bool PropertyNameCaseInsensitive { get; set; }
例子:
string jsonSchema = """
{
"properties": {
"A": {
"properties": {
"B": {"type": "string"}
}
}
}
}
""";
string jsonInstance = """
{
"a": {
"b": 123
}
}
""";
// By default, JSON Schema validation is property names case sensitive, so instance data's property names are not matched:
ValidationResult validationResult = new JsonValidator(jsonSchema).Validate(jsonInstance);
Assert.True(validationResult.IsValid);
// Opt in to feature of property names case Insensitive:
validationResult = new JsonValidator(jsonSchema, new JsonValidatorOptions { PropertyNameCaseInsensitive = true }).Validate(jsonInstance);
Assert.False(validationResult.IsValid);
Assert.Equal("Expect type(s): 'String' but actual is 'Number'", validationResult.ErrorMessage);
Assert.Equal("/a/b", validationResult.InstanceLocation!.ToString());
Assert.Equal("/properties/A/properties/B/type", validationResult.RelativeKeywordLocation!.ToString());
總結
本文介紹了.NET下 實現屬性名大小寫無關的JSON Schema驗證方法,其中最優雅的方式應該是用 .NET實現庫 Lateapexearlyspeed.Json.Schema
中的擴展選項 PropertyNameCaseInsensitive
。
歡迎大家將使用過程中發現的問題報到repo issue,希望.NET實現庫 Lateapexearlyspeed.Json.Schema
能幫到大家。
Github repo: https://github.com/lateapexearlyspeed/Lateapexearlyspeed.JsonSchema