最近项目中遇到了这样的需求,需要对上传的Json进行验证,以确保Json数据的准确性。前后使用了两种方式来验证:

 

  (1)第一种方式的实现思想:根据Json数据的格式,严格定义相应的类结构,并在System.Runtime.Serialization命名空间下的DataContractAttribute、DataMemberAttribute对class和property进行标注,如果property是必须提供的,则在Property上添加[DataMember(IsRequired = true)]。

  然后使用Newtonsoft.Json程序集中的JsonConvert.DeserializeObject<T>()方法加需要验证的JsonContent反序列化一下,并用try...catch包含反序列化语句,如果转换成功,则表明JsonContent格式满足要求。如果转换不成功,则会抛出异常,有catch接住。

  

  

            try
{
var obj = JsonConvert.DeserializeObject<SkuConfigEntity>(skuManifest, new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Error
});
}
catch(Exception e)
{
return false;
}

  

这种方法是最初使用的方法,个人认为不完善,也不够完美,转换出错的情况加,exception中不能给出具体的出错原因。

  (2)第二种实现思想:Json Schema(Json 模式)。在前辈的指点下,我知道了Json Schema,

 JSON 模式是一种基于 JSON 格式定义 JSON 数据结构的规范。它被写在 IETF 草案下并于 2011 年到期。JSON 模式:

  • 描述现有数据格式。
  • 干净的人类和机器可读的文档。
  • 完整的结构验证,有利于自动化测试。
  • 完整的结构验证,可用于验证客户端提交的数据。

JSON 模式验证库

目前有好几个验证器可用于不同的编程语言。但是目前最完整和兼容 JSON 模式的验证器是 JSV。

语言 程序库
C WJElement (LGPLv3)
Java json-schema-validator (LGPLv3)
.NET Json.NET (MIT)
ActionScript 3 Frigga (MIT)
Haskell aeson-schema (MIT)
Python Jsonschema
Ruby autoparse (ASL 2.0); ruby-jsonschema (MIT)
PHP php-json-schema (MIT). json-schema (Berkeley)
JavaScript Orderly (BSD); JSV; json-schema; Matic (MIT); Dojo; Persevere (modified BSD or AFL 2.0); schema.js.

   

 

JSON 模式示例

下面是一个基本的 JSON 模式,其中涵盖了一个经典的产品目录说明:

{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
}
},
"required": ["id", "name", "price"]
}

我们来看一下可以用于这一模式中的各种重要关键字:

关键字 描述
$schema $schema 关键字状态,表示这个模式与 v4 规范草案书写一致。
title 用它给我们的模式提供了标题。
description 关于模式的描述。
type type 关键字在我们的 JSON 数据上定义了第一个约束:必须是一个 JSON 对象。
properties 定义各种键和他们的值类型,以及用于 JSON 文件中的最小值和最大值。
required 存放必要属性列表。
minimum 给值设置的约束条件,表示可以接受的最小值。
exclusiveMinimum 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上大于 "minimum" 的值则实例有效。
maximum 给值设置的约束条件,表示可以接受的最大值。
exclusiveMaximum 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上小于 "maximum" 的值则实例有效。
multipleOf 如果通过这个关键字的值分割实例的结果是一个数字则表示紧靠 "multipleOf" 的数字实例是有效的。
maxLength 字符串实例字符的最大长度数值。
minLength 字符串实例字符的最小长度数值。
pattern 如果正则表达式匹配实例成功则字符串实例被认为是有效的。

上述的Json模式可以验证如下Json串。

[
{
"id": 2,
"name": "An ice sculpture",
"price": 12.50
},
{
"id": 3,
"name": "A blue mouse",
"price": 25.50
}
]

在.Net中,Json Schema 通过Newtonsoft.Json.Schema命名空间下的JsonSchema类可以实现。

每一个JsonSchema实例表示对一个Property的描述以及限制。

    JsonSchema class的几个关键属性:

Type 设置Property的类型  
Required 设置Property是否为必须的  
Properties 包含的所有下一级Property的JsonSchema,该属性是Dictionary<string,JsonSchema>类型,添加子项之前需初始化。  
Items 包含的所有下一级的数组项的JsonSchema,该属性是IList<JsonSchema>类型,添加子项之前需要初始化。  
     
     
     

使用Newtonsoft.Json.Schema命名空间下的IsValid()扩展方法,可实现对Json串的验证,该方法是JToken的扩展方法。

    public static JsonSchema GetSkuJsonSchema()
    {

    JsonSchema rootSchema = new JsonSchema() { Title = "Sku.Json", Type = JsonSchemaType.Object };

            rootSchema.Properties = new Dictionary<string, JsonSchema>();
rootSchema.Properties.Add("name", new JsonSchema() { Type = JsonSchemaType.String, Required = true });
rootSchema.Properties.Add("displayName", new JsonSchema() { Type = JsonSchemaType.String, Required = true });
rootSchema.Properties.Add("apimInstance", new JsonSchema() { Type = JsonSchemaType.String, Required = true });
rootSchema.Properties.Add("apiPath", new JsonSchema() { Type = JsonSchemaType.String, Required = true }); JsonSchema skuSchema = new JsonSchema() { Title = "skus", Type = JsonSchemaType.Array, Required = true };
skuSchema.Properties= new Dictionary<string, JsonSchema>();
skuSchema.Properties.Add("name", new JsonSchema() { Type = JsonSchemaType.String, Required = true });
skuSchema.Properties.Add("tier", new JsonSchema() { Type = JsonSchemaType.String, Required = true });
skuSchema.Properties.Add("subscriptionSkuQuota", new JsonSchema() { Type = JsonSchemaType.Integer, Required = false });
skuSchema.Properties.Add("skutype", new JsonSchema() { Type = JsonSchemaType.String, Required = false });
skuSchema.Properties.Add("skuquota", new JsonSchema() { Type = JsonSchemaType.String, Required = false });
skuSchema.Properties.Add("apimProductId", new JsonSchema() { Type = JsonSchemaType.String, Required = false }); JsonSchema locationsSchema = new JsonSchema() { Title = "locations", Type = JsonSchemaType.Array, Required = true };
locationsSchema.Properties= new Dictionary<string, JsonSchema>();
locationsSchema.Properties.Add("location", new JsonSchema() { Type = JsonSchemaType.String, Required = true });
locationsSchema.Properties.Add("apimProductId", new JsonSchema() { Type = JsonSchemaType.String, Required = false });
skuSchema.Properties.Add("locations", locationsSchema); JsonSchema meterIdsSchema = new JsonSchema() { Title = "meterIds", Type = JsonSchemaType.Array, Required = true };
meterIdsSchema.Items = new List<JsonSchema>();
meterIdsSchema.Items.Add(new JsonSchema() { Type = JsonSchemaType.String, Required = false });
skuSchema.Properties.Add("meterIds", meterIdsSchema); JsonSchema requiredFeaturesSchema = new JsonSchema() { Title = "requiredFeatures", Type = JsonSchemaType.Array, Required = true };
requiredFeaturesSchema.Items = new List<JsonSchema>();
requiredFeaturesSchema.Items.Add(new JsonSchema() { Type = JsonSchemaType.String, Required = false });
skuSchema.Properties.Add("requiredFeatures", requiredFeaturesSchema); rootSchema.Properties.Add("skus", skuSchema); return rootSchema;
  }

  

JToken jtoken=JToken.Parse(jsonContent);

IList<string> errorList;

var result=jtoken.IsValid(schema, out errorList);

如果验证成功,则返回ture,如果验证失败,则返回false,并且errorList中会包含详细的错误信息。

.Net使用JsonSchema验证Json的更多相关文章

  1. Json.Net使用JSON Schema验证JSON格式

    Json.NET supports the JSON Schema standard via the JsonSchema and JsonValidatingReader classes. It s ...

  2. 利用JsonSchema校验json数据内容的合规性(转)

    原文地址:Json schema 背景: 复杂的AJAX应用程序可以与数百个不同的JSON服务进行交互,因此,引入对客户端验证的需求. 在处理校验问题方面有着很多的工具,但是通常可以将它们归为以下几类 ...

  3. Json.Net使用JSON Schema验证JSON格式【实例】

    给出一个Json,验证其格式是否符合规则. { "coord": { //对象 "lon": 145.77, "lat": -16.92 } ...

  4. php的json校验json-schema

    客户端和服务端的http信息传递,采用json几乎成了标配.json格式简单,易于处理,不过由于没有格式规定,无法校验. 好在php有json-schema模块,可以用来验证json是否符合规定的格式 ...

  5. Json schema 以及在python中的jsonschema

    目录 1. JSON Schema简介 2. JSON Schema关键字详解 2.1 $schema 2.2 title和description 2.3 type 3 type常见取值 3.1 当t ...

  6. Postman使用tv4进行JSON Schema结构验证和断言

    JSON Scheme简介 对于JSON格式的请求数据或者响应数据,在不同的数据和场景下往往会有一部分动态的值及字段.此时我们可以使用JSON Scheme Validator(JSON结构验证)来验 ...

  7. 【AMAD】jsonschema -- (又)一个JSON Schema的Python实现

    动机 简介 用法 个人评分 动机 JSON Schema1是一个专业词汇,可以让你注解和验证JSON文档. 使用JSON Schema的好处有: 描述你的数据格式 提供清晰的易读的文档 验证数据: 用 ...

  8. 技术那么多,你想看看JSON Schema的测试吗?

    目录 1. 什么是JSON Schema? 2. 如何定义一个JSON Schema 3. 如何测试JSON Schema a) 使用JSON Schema validator GUI b) 在Jav ...

  9. JSON Schema 校验实例

    JSON Schema 简介 JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. ...

随机推荐

  1. Mac下安装node.js和webpack

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "PingFang SC"; color: #393939 } p.p2 ...

  2. 关于Container With Most Water的求解

    Container With Most Water 哎,最近心情烦躁,想在leetcode找找感觉,就看到了这题. 然而,看了题目半天,硬是没看懂,于是乎就百度了下,怕看到解题方法,就略看了下摘要,以 ...

  3. Unity启动事件-监听:InitializeOnLoad

    [InitializeOnLoad] :在启动Unity的时候运行编辑器脚本  官方案例: using UnityEngine; using UnityEditor; [InitializeOnLoa ...

  4. Exchange 2010 实用小技巧

    #Exchange安装必须开启防火墙服务 #批量建用户: for /f  "tokens=1,2,3,4,5,6,7 delims=," %a in (c:\users.csv) ...

  5. iOS UIImageView自适应图片大小

    窗口大小获取: CGRect screenBounds = [ [UIScreenmainScreen]bounds];//返回的是带有状态栏的Rect CGRect rect = [ [UIScre ...

  6. C#删除只读文件或文件夹(解决File.Delete无法删除文件)

    引用: http://www.jb51.net/article/72181.htm   C#删除只读文件的方法: if (File.GetAttributes(FFName).ToString().I ...

  7. Struts2的通配符配置方式

    Struts2的Action类很有意思,你可以使用3种方式来实现具体的Action类: 让你的Action类继承自ActionSupport类(项目中最常用这种方式,因为ActionSupport类中 ...

  8. 面试题-Java基础-线程部分

    1.进程和线程的区别是什么? 进程是执行着的应用程序,而线程是进程内部的一个执行序列.一个进程可以有多个线程.线程又叫做轻量级进程. 2.创建线程有几种不同的方式?你喜欢哪一种?为什么? 有三种方式可 ...

  9. SAP HANA中创建计算视图(Calculation View)

    [Step By Step]SAP HANA中创建计算视图(Calculation View) Demo Instruction: 该视图将两个表AUDIOBOOKS和BOOKS中的数据进行连接,并作 ...

  10. NOIP2013-普及组初赛C语言解析

    第十九届全国青少年信息学奥林匹克联赛初赛 一.单项选择题(共 20 题,每题 1.5 分,共计 30 分.每题有且仅有一个正确选项)1. 一个 32 位整型变量占用(A )个字节.A. 4 B. 8 ...