Reputation: 583
I'm in the process of testing an API that returns JSON. The value returned has child objects (a date object with from and to properties for example). I have a sample JSON string and the string being returned by the API. What's the best way to compare the two by key only and not value so that only the structure of the JSON is compared (using C# in this instance in case that has any baring)? I've seen similar questions being asked but not quite what I'm looking for.
The JSON in the question at the moment looks something like this:
{
"collection":[{
"timePeriod":{
"from": "2017-01-01",
"to": "2017-02-01"
},
"type": "a",
"amount": 463872,
"outstanding": 463872,
"due": "2017-03-08"
}]
}
Upvotes: 3
Views: 1844
Reputation: 18179
One solution is to use the Json.NET and Json.NET Schema nuget packages to validate your JSON string against a JSON schema.
You can create a JSON schema or generate one based on C# objects. In this case, I generated some classes that matches your JSON structure (sorry about the class names):
public class RootObject
{
[JsonProperty("collection", Required = Required.Always)]
public List<Item> Collection { get; set; }
public RootObject()
{
Collection = new List<Item>();
}
}
public class Item
{
[JsonProperty("timePeriod", Required = Required.Always)]
public TimePeriod TimePeriod { get; set; }
[JsonProperty("type", Required = Required.Always)]
public string Type { get; set; }
[JsonProperty("amount", Required = Required.Always)]
public int Amount { get; set; }
[JsonProperty("outstanding", Required = Required.Always)]
public int Outstanding { get; set; }
[DataType(DataType.Date)]
[JsonProperty("due", Required = Required.Always)]
public DateTime Due { get; set; }
}
public class TimePeriod
{
[DataType(DataType.Date)]
[JsonProperty("from", Required = Required.Always)]
public DateTime From { get; set; }
[DataType(DataType.Date)]
[JsonProperty("to", Required = Required.Always)]
public DateTime To { get; set; }
}
I am assuming all properties are required. Also, regarding the DateTime properties I am using Data Annotations to specify that the dates do not contain the time part (as opposed to a full ISO date).
Validating the schema:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Schema.Generation;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string json = @"{
""collection"":[{
""timePeriod"":{
""from"": ""2017-01-01"",
""to"": ""2017-02-01""
},
""type"": ""a"",
""amount"": 463872,
""outstanding"": 463872,
""due"": ""2017-03-08""
}]
}";
var generator = new JSchemaGenerator();
JSchema schema = generator.Generate(typeof(RootObject));
JObject data = JObject.Parse(json);
bool isValidSchema = data.IsValid(schema);
}
}
}
You can also get the schema errors as following:
IList<string> messages;
bool isValidSchema = data.IsValid(schema, out messages);
foreach (string message in messages)
{
Console.WriteLine(message);
}
Upvotes: 3