When I'm serialising to JSON, I'm used to .NET dictionaries becoming objects with the keys as properties and the values as their values. (The Json.Net docs have a succinct example.)
I'm using GraphQL and struggling to achieve a similar result. My data for this root query is basically a Dictionary<MyEnum,Dictionary<string,string>>. The closest I've got so far is this:
{
"data": {
"outterDict": [
{
"key": "THING_1",
"innerDict": [
{
"key": "key1",
"val": "val1"
},
...
]
},
{
"key": "THING_2",
"innerDict": [
{
"key": "key2",
"val": "val2"
},
...
]
}
]
}
}
But I want it to be closer to this:
{
"data": {
"collection": {
"THING_1": {
"key1": "val1",
...
},
"THING_2": {
"key2": "val2",
...
}
}
}
}
I'm struggling because GraphQL .Net only seems to understand lists, not dictionaries.
It doesn't feel like what I'm trying to do is unreasonable. Letting keys be keys seems right and like the most useful way to share this data (e.g. as suggested by this answer).
Is there a way to do this in GraphQL? Is there a way to do this in GraphQL .Net?
After quite of lot of research, it seems like this isn't in the spec of GraphQL and is therefore unsupported in GraphQL.Net.
GraphQL expects all possible properties (i.e. keys in a map/dictionary) to be known in advance. This means we lose a lot of the value of passing a dictionary at run time.
So although the GraphQL JSON is more verbose than idiomatic JSON, it's like this deliberately.
Related
I have this JSON that's a list of objects, like this.
"Fields": [
{
"fieldID": 1,
"name": "field"
}
]
When the list is empty, it is sent like this
"Fields": [
{}
]
I read this in as a string and then try to deserialize it using JsonConvert.DeserializeObject<List<T>>(json); where T is the object that matches the field model. When I do this though, I get a new list with one item in it (count = 1 when it should be 0), the same as if I deserialized this JSON.
"Fields": [
{
"fieldID": 0,
"name": null
}
]
How can I avoid or work around this?
First following json does not represent empty list:
"Fields": [
{}
]
An empty list in json should look like following:
"Fields": []
So you should try to fix the json. However, if that's proven to be impossible you can do something like following:
using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
var l = root.EnumerateArray().First().ToString();
if(l=="{}")
{
//do something
}
}
What's happening is that you simply parsing the json and enumerate through the list of element and detect if "{}" exists.
Or, you can go with a more complex way which is writing a custom converter which handles such case in the way you want. You can check out the documentation here
I searched first, and basically I am trying to avoid having to use JObject in C# in favor of ANY Serializer. An excerpt of a large Microsoft Dynamics JSON trace has JSON formed like this
{
"InBlockOStuff" :
{
"type":"Yea You Know What this is",
"values":[
{
"Key":"Target",
"Value":{
"type":"Yea You Know What this is",
"LogicalName":"Thangie",
"Id":"GuidAs String",
"MagicalContent":{
"type":"Yea You Know What this is",
"values":[
{
"Key":"firstname",
"Value":"New Test thangie One"
},
{
"Key":"Thangieid",
"Value":"some stupid Guid like thangie"
}
]
},
"Shaggy":null,
"SubCategory":{
"type":"Yea You Know What this is",
"values":[ ]
},
"Velma":{
"type":"Yea You Know What this is",
"values":[ ]
},
"Scoobie":null,
"KeyAttributes":{
"type":"Yea You Know What this is",
"values":[ ]
}
}
},
{
"Key":"some text",
"Value":true
},
{
"Key":"some text",
"Value":0
}
]
}
}
Notice the repeated instances of the "keys" value and values It is valid Json, the online validators say it is legit, the online generators will additionally create C# classes/objects but I'm sure you instantly see this mess will have two distinctly different "Values" classes. And that doesn't serialize cleanly.
So am I stuck having to learn JObject to get my data out of this mess?
This is just high level excerpt there exists, for example another MagicalContent key with a different set of key values inside of it, just for arguments sake.
I have a JSON document coming from a vendor that looks like this:
{
"content": [{
"name": "Windows 8.1 x64",
"id": "Windows81x64",
"components": {
"Windows81x64": {
"propertyGroups": ["VirtualWindows81x64"],
"dependsOn": [],
"data": {
"provisioning_workflow": {
"fixed": {
"id": "WIMImageWorkflow",
"label": "WIMImageWorkflow"
}
},
"memory": {
"default": 2048,
"min": 2048,
"max": 16384
}
}
}
}
}]
}
Most of this document is fairly easy to deserialize into an object using the typical DataContractSerializer, however, there are a couple of keys/values that I am not sure what the "best practice" might be.
If you look at the "components" key the first key after that one is titled "Windows81x64". This key can change from document to document and it can be any value. It almost should be a 'Name' property of the collection but I can't control that. Furthermore, inside the 'Windows81x64' key there is another property called 'data'. According to the vendor the value of data is 'anonymous.' So, basically it can be anything.
Any ideas on the best way to deserialize this into a custom object when it comes to those parts of the document? Thank you.
You can deserialize dynamic ones as Dictionary<string, object>
Or if you know the value's type you can use Dictionary<string, ValueType> where the key of the dictionary would be the name (in your case Windows81x64)
I want to deserialize a json that I get as result of a REST query (the json string can not be changed) to a dictionary type.
The json string looks something like this:
{
"collection": {
"useful": true
"attributes": {
"ObjectID": "ObjectID",
"Name": "Name",
"FirstID": "FirstID",
"LastID": "LastID",
"Count": "5",
},
"Type": "Polyline",
"features": [{
"attributes": {
"length": 0.10879009704943393
"time": 0.3822371137674949,
"text": "some text",
"ABC": -2209161600000,
"Type": "SomeType"
}
}]
}
}
I create boolean property for 'useful' and integer for 'count' etc. but I have a problem with the 'attributes'. As you can see, in each section (and per result) I get different 'attributes'.
I need to deserialize them into some generic collection like dictionary or list of KeyValuePair. the problem is, as stated in msdn (here - http://msdn.microsoft.com/en-us/library/bb412170.aspx) "Dictionaries are not a way to work directly with JSON".
How can I do it if so?
My application is silverlight 5, .Net 4, VS 2010.
Thanks in advance!
Good morning everyone. I have a service which returns me a JSON response (something like below):
{
"sessionid": "AQIC5wM2LY4SfcytTIcteNkTtCVrE8A-AS7VR*",
"Customers": [
{
"id": "4193942846",
"firstname": "Anto",
"lastname": "Paul",
"customertype": "ph",
"companyCode": "ABCD",
},
{
"id": "4193942236",
"firstname": "Dimple",
"lastname": "Paul",
"customertype": "ph",
"companyCode": "AB",
}
],
"Status": "ACTIVE",
"serviceStatus": "SUCCESS",
"Addresses": {
"Address": [
{
"type": "M",
"addr1": "11011, main st",
"addr2": "Apt. 2",
"zipcode": "11011"
}
]
}
}
The above structure varies based on the input I pass to the service. So, I cant contruct one class to deserialize the response. I need to compare (attribute-attribute comparison) this response to a response I already have with me (in a different place).
I tried to do it with dynamic class in C# but no luck so far. Could someone share a better,working approach? Thank you.
You can use JToken.DeepEquals like this:
var response = JObject.Parse(responseJson);
var goldenStandard = JObject.Parse(goldenStandardJson);
if (JToken.DeepEquals(response, goldenStandard))
{
// the two JSONs have the same data
}
Try Json.Net. It supports dynamic structures.
Here is a tutorial:
http://www.codeproject.com/Tips/631586/Dynamic-types-with-JSON-NET
Use this:
https://jsonutil.codeplex.com/
var obj1 = JSONSerializer.Deserialize(jsontext1);
var obj2 = JSONSerializer.Deserialize(jsontext2);
bool Compare(object obj1, object obj2)
{
//if(obj1 is JSONObject && obj2 is JSONObject)
// => typecase and use jsonObj1.Members to iterate over members and compare values recursively
//if JSONArray, then iterate over items and compare
//if anything else... i.e. primitive then compare directly
//else return false;
}
If you are using this JSON response one time, then you can use a dynamic JSON NET types.
But if you are using this JSON structure response some times, then it is preferable to make this response to a c# classes (objects), so you will have a very easy access to it's properties, you just have your c# objects and they have properties and you can simply approach to each field you wish (with intellisense). By the way, it is very easy to copy a JSON response to a C# classes (something like copy paste). Here is how to do that:
http://blogs.msdn.com/b/webdev/archive/2012/12/18/paste-json-as-classes-in-asp-net-and-web-tools-2012-2-rc.aspx