C# - JSON Schema validation

C# - JSON Schema validation

  • 引言
  • 如何生成 C# 类 JSON Schema
    • 利用在线工具
    • 利用 Visual Studio
    • 利用 NJsonSchema
  • 验证 JSON Schema
    • 针对 JSON Schema 字符串
    • 针对 C# 类 Schema

引言

针对 API 测试,我们需要验证 Response 中的一些字段类型,是否缺省等,现在有一些开源的插件就可以实现,很方便。

之前 Java API 测试 《 REST Assured 系列汇总 》有介绍 REST Assured JSON Schema 验证,可以参考下面三篇文章:

REST Assured 54 - What Is JSON Schema?

REST Assured 55 - JSON Schema Validation In Rest Assured

REST Assured 56 - JSON Schema Validation Without Rest Assured

今天介绍 C# API 测试有关 JSON Schema validation,怎么将 JSON 生成 C# 类文件,以及如何验证 JSON Schema。

如何生成 C# 类 JSON Schema

主要有三种方式将 JSON response 自动生成 C# 类 JSON Schema,各有特色。

利用在线工具

用在线工具 quicktype 生成最方便了, 还可以进行一些设置。

例如:简单的一个 JSON

{
  "ID": "1002",
  "Name": "ABCD",
  "City": "city",
  "Country": "USA",
  "hobby": ["reading", "travel"]
}

C# - JSON Schema validation_第1张图片

利用 Visual Studio

Visual Studio 有个 “Paste Special” 功能用来创建 JSON c# classes.
Visual Studio – -> Edit — > Paste Special

具体步骤如下:

  1. 创建一个 C# 文件
  2. copy 下面 JSON 内容到剪贴板
{
  "ID": "1002",
  "Name": "ABCD",
  "City": "city",
  "Country": "USA",
  "hobby": ["reading", "travel"]
}
  1. 打开步骤 #1 中创建的 C# 文件,然后打开菜单 Visual Studio --> Edit – > Paste Special–> Past JSON As Classes
    C# - JSON Schema validation_第2张图片
  2. 在C# 文件中就自动生成了下面这个类
    我们需要做一些改动,例如类名,加一些 Attributs
 public class Rootobject
    {
        public string ID { get; set; }
        public string Name { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string[] hobby { get; set; }
    }

利用 NJsonSchema

NJsonSchema 是一个 .NET library 用来读,生成,验证 JSON Schema. 它提供了基本的 APIs,可以用来从一个 JSON Schema 生成 C# 类,或生成 TypeScript 类,或接口。更多细节可参考《 Autogenerate C# Class using JSON string or JSON Schema 》

  1. 首先需要装下面这个 NuGet package.C# - JSON Schema validation_第3张图片
  2. 准备一个 json 文件,注意将属性设置为 Copy always
    C# - JSON Schema validation_第4张图片
  3. 创建一个 Generator 文件
    注意命名空间 using JsonSchema = NJsonSchema.JsonSchema;
using NJsonSchema.CodeGeneration.CSharp;
using JsonSchema = NJsonSchema.JsonSchema;

namespace ConsoleApp
{
    public class Generator
    {
        static void Main(string[] args)
        {
            string json = File.ReadAllText("js.json");
            var schemaFromFile = JsonSchema.FromSampleJson(json);
            var classGenerator = new CSharpGenerator(schemaFromFile, new CSharpGeneratorSettings
            {
                ClassStyle = CSharpClassStyle.Poco,
            });
            var codeFile = classGenerator.GenerateFile();
            File.WriteAllText("JSONSchemaClass.cs", codeFile);

        }
    }
}
  1. 运行一下,看看生成的 JSONSchemaClass.cs 文件
    注意路径在 bin 目录下。
//----------------------
// 
//     Generated using the NJsonSchema v10.8.0.0 (Newtonsoft.Json v9.0.0.0) (http://NJsonSchema.org)
// 
//----------------------


namespace MyNamespace
{
    #pragma warning disable // Disable all warnings

    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.8.0.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Anonymous
    {
        [Newtonsoft.Json.JsonProperty("ID", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string ID { get; set; }

        [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Name { get; set; }

        [Newtonsoft.Json.JsonProperty("City", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string City { get; set; }

        [Newtonsoft.Json.JsonProperty("Country", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Country { get; set; }

        [Newtonsoft.Json.JsonProperty("hobby", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Collections.Generic.ICollection<string> Hobby { get; set; }



        private System.Collections.Generic.IDictionary<string, object> _additionalProperties;

        [Newtonsoft.Json.JsonExtensionData]
        public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
        {
            get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>()); }
            set { _additionalProperties = value; }
        }

    }
}

验证 JSON Schema

首先需要安装 NJsonSchema NuGet 包
C# - JSON Schema validation_第5张图片

针对 JSON Schema 字符串

可以参考这遍文章《 C# JSON Schema validation 》这个例子还能运用在异步代码上。

namespace ConsoleApp
{
    using NJsonSchema;
    using System;
    using System.Threading.Tasks;
 
    class ValidateJSONSchema
    {
        static async Task Main()
        {
 
            var jsonSchema = @"
                {
                    ""type"": ""object"",
                    ""properties"": {
                        ""name"": {
                            ""type"": ""string""
                        },
                        ""age"": {
                            ""type"": ""integer"",
                            ""minimum"": 0
                        },
                        ""isMarried"": {
                            ""type"": ""boolean""
                        }
                    }
                 }
            ";
 
            var jsonDataValid = @"
                {
                    ""name"": ""Jay"",
                    ""age"": 20,
                    ""isMarried"": true
                }
            ";
 
            var jsonDataInvalid = @"
                {
                    ""name"": ""Jay"",
                    ""age"": ""20"",
                    ""isMarried"": ""true""
                }
            ";
 
            var schema = await JsonSchema.FromJsonAsync(jsonSchema);
 
            var errorsForValidJson = schema.Validate(jsonDataValid);
            var errorsForInvalidJson = schema.Validate(jsonDataInvalid);
 
            Console.WriteLine("valid errors:");
            foreach (var error in errorsForValidJson) Console.WriteLine(error);
 
            Console.WriteLine("invalid errors:");
            foreach (var error in errorsForInvalidJson) Console.WriteLine(error);
 
        }
    }
}

运行结果如下:

C# - JSON Schema validation_第6张图片

针对 C# 类 Schema

利用前面介绍的方法,将生成的 C# 类 JSON Schema 文件添加到项目中。

using Newtonsoft.Json;

namespace ConsoleApp
{
    public class JSONSchema
    {
        [JsonProperty("ID", Required = Required.Always)]
        public string Id { get; set; }

        [JsonProperty("Name", Required = Required.Always)]
        public string Name { get; set; }

        [JsonProperty("City", Required = Required.Always)]
        public string City { get; set; }

        [JsonProperty("Country", Required = Required.Always)]
        public string Country { get; set; }

        [JsonProperty("hobby", Required = Required.Always)]
        public List<string> Hobby { get; set; }

       }
}

C# - JSON Schema validation_第7张图片

利用反射机制将 C# 类解析成 JsonSchema
string schemaName = “JSONSchema”;
Type type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(x => x.Name == schemaName);
var schema = JsonSchema.FromType(type);

using Newtonsoft.Json.Linq;
using NJsonSchema;
using System.Reflection;

namespace ConsoleApp
{
    public class ValidateJSONSchema
    {

    static void Main(string[] args)
        {
            //string data = "";
            string jsonDataValid = @"
               {
                  ""ID"": ""1002"",
                  ""Name"": ""ABCD"",
                  ""City"": ""city"",
                  ""Country"": ""USA"",
                  ""hobby"": [""reading"", ""travel""]
                }
            ";
            string schemaName = "JSONSchema";
            Type type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(x => x.Name == schemaName);
            if (type == null)
                throw new Exception($"Schema {schemaName} not found");

            JToken Data = JToken.Parse(jsonDataValid);

            var schema = Data.Type == JTokenType.Array ?
             JsonSchema.FromType(typeof(List<>).MakeGenericType(new[] { type })) :
             JsonSchema.FromType(type);

            var errors = schema.Validate(jsonDataValid);
            Console.WriteLine(errors.Count.ToString());
            Console.WriteLine(string.Join(System.Environment.NewLine, errors));
            
        }
    }
}

你可能感兴趣的:(C#,c#,json,NJsonSchema,Json,Schema,API,测试)