最近项目中遇到了这样的需求,需要对上传的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. hdu 1299 Diophantus of Alexandria(数学题)

    题目链接:hdu 1299 Diophantus of Alexandria 题意: 给你一个n,让你找1/x+1/y=1/n的方案数. 题解: 对于这种数学题,一般都变变形,找找规律,通过打表我们可 ...

  2. Long类型比较大小,long型和Long型区别

    今天写代码发现发现本地程序是正常的,但是发送到测试环境就不正常了,本着对数据的怀疑态度链接了测试数据库,调试程序发现,确实是数据问题,然后数据出现在什么地方呢?才发现是在判断用户所属的teamGrou ...

  3. COCOS2D-JS入门-官网template源码解析

    首先介绍几个概念: 导演: 导演 (Director)是Cocos2d-JS引擎抽象的一个对象,Director是整个Cocos2d-JS引擎的核心,是整个游戏的导航仪,游戏中的一些常用操作就是由Di ...

  4. POJ 3507 Judging Olympia

    小技巧 判断 全部为零 用sign和所有元素依次取或 排除最大项和最小项 直接排序后取中间的四个元素 http://poj.org/problem?id=3507 1 #include <ios ...

  5. 设计模式 -- 中介者设计模式 (Mediator Pattern)

    中介者模式的定义:将多对多关系分散为一对多的关系,将网状结构变成星状结构,降低复杂度,提高扩展性. 角色: Mediator :抽象中介者角色,以抽象类的方式实现,生命具体对象,以及抽象方法: Con ...

  6. mozilla your firefox profile cannot be loaded. it may be missing or inaccessible

    check the permissions ls -l ~/.cache | grep mozilla fix the permissions sudo chown -R $USER:$USER ~/ ...

  7. 日期的本质是double

    日期的本质是double,在多语种时用起来更方便.

  8. eclipse背景主题

    长时间对着电脑敲代码,眼睛受不了啊,果然程序员就没人权吗?之前咱给codeblocks背景换了颜色,去官网上粘粘代码然后替换一下就行了,这里不多说, 这里说的是给ecllipse换主题,按理说ecli ...

  9. 使用inno setup制作安装包

  10. 制作jar包

    1.打开cmd 2.通过cd切换到要打包的工程所在的bin目录(一定是bin目录) 运行jar -cvf aa.jar *.* jar是打包的命令 -cvf可以自行查看一下文档解释(jar -help ...