I want to extract a JSON schema (as defined here) from an object of type dynamic.
This is the best example I could find.
But JSON.NET's Schema Generator needs to look at an actual class/type to be able to generate a schema.
Anyone have any ideas on how I could extract a schema from a dynamic object?
You can still use JSON.NET to extract a JSON schema from dynamic object. You just need an actual object of type dynamic to be able to do that. Try the following sample:
dynamic person = new
{
Id = 1,
FirstName = "John",
LastName = "Doe"
};
JsonSchemaGenerator schemaGenerator = new JsonSchemaGenerator {};
JsonSchema schema = schemaGenerator.Generate(person.GetType());
The generated JSON schema should look like this:
{
"type": "object",
"additionalProperties": false,
"properties": {
"Id": {
"required": true,
"type": "integer"
},
"FirstName": {
"required": true,
"type": [
"string",
"null"
]
},
"LastName": {
"required": true,
"type": [
"string",
"null"
]
}
}
}
If you are using .NET 4.0+ then there is a method System.Web.Helpers.Json.Decode that converts JSON into a dynamic object:
using System.Web.Helpers;
// convert json to a dynamic object:
var myObject = Json.Decode(json);
// or to go the other way and get json from a dynamic object:
string myJson = Json.Encode(myObject);
To reference this assembly you can find it in the Extensions group under Assemblies in Visual Studio 2012.
This should be able solve your problem. If you can include a sample of the JSON it would be clearer.
Related
How to covert the below json
{"data":{"id":12,"name":"jeremy","email":"jeremy#test.com"}}
to
{"id":12,"name":"jeremy","email":"jeremy#test.com"}
I want to remove the "data" element from json.
With json.net it's fairly straightforward
var input = "{\"data\":{\"id\":12,\"name\":\"jeremy\",\"email\":\"jeremy#test.com\"}}";
var result = JObject.Parse(input)["data"].ToString(Formatting.None);
Console.WriteLine(result);
Note : Formatting.None is only to preserve the formatting you had in your original example
Or Text.Json
var result = JsonDocument.Parse(input).RootElement.GetProperty("data").ToString();
Output
{"id":12,"name":"jeremy","email":"jeremy#test.com"}
Additional Resources
JObject.Parse Method (String)
Load a JObject from a string that contains JSON.
JObject.Item Property (String)
Gets or sets the JToken with the specified property name.
JToken.ToString Method (Formatting,JsonConverter[])
Returns the JSON for this token using the given formatting and
converters.
Formatting Enumeration
None 0 No special formatting is applied.
Text.Json
JsonDocument.Parse Method
Provides a mechanism for examining the structural content of a JSON
value without automatically instantiating data values.
JsonDocument.RootElement Property
Gets the root element of this JSON document
JsonElement.GetProperty Method
Gets a JsonElement representing the value of a required property
identified by propertyName.
I have a follow up question on a scenario where I don't want to remove the root element.
{
"keepMe": {
"removeMe": [
{
"id": "1",
"name": "Foo",
"email": "Foo#email.com"
},
{
"id": "2",
"name": "Bar",
"email": "Bar#email.com"
}
]
}
But I wanted it to look like
{
"keepMe": {
{
"id": "1",
"name": "Foo",
"email": "Foo#email.com"
},
{
"id": "2",
"name": "Bar",
"email": "Bar#email.com"
}
}
Using below would not work. Is there another way to do this?
var result = JObject.Parse(input)["keepMe"]["removeMe"].ToString(Formatting.None);
//{
// "id": "1",
// "name": "Foo",
// "email": "Foo#email.com"
//},
//{
// "id": "2",
// "name": "Bar",
// "email": "Bar#email.com"
//}
var result = JObject.Parse(input)["removeMe"].ToString(Formatting.None); //Null Reference
Found the answer using the SelectToken and Replace keyword
var jObj = JObject.Parse(input);
jObj.SelectToken("keepMe").Replace(jObj.SelectToken("keepMe.removeMe"));
string result = jObj.ToString();
I have below JSON schema which works ok with JsonConvert.DeserializeObject. I am able to extract schema directly from it but when it comes to JSON Data string, then I am not sure how to extract schema.
{
"fields": [
{
"name": "approved",
"type": "Boolean",
"displayName": "Approved",
"isNullable": true,
"isSearchable": false,
"isFilter": true,
"isInternal": false
}
]
}
In the above JSON, approved is the field name so I am able to extract schema, but I have a JSON data string as below and want to extract schema from it.
{
"skuId": "1",
"balance": [
{
"warehouseId": "1_1",
"warehouseName": "Main Warehouse",
"totalQuantity": 1000001,
"reservedQuantity": 1,
"hasUnlimitedQuantity": true,
"timeToRefill": null,
"dateOfSupplyUtc": null
}
]
}
In the above example JSON data, warehouseid, warehousename, etc., are fieldname and I need to have those in my schema in c#.
Can anyone please suggest?
create a new class, copy your json data string, and in visual studio click edit -> paste special, and it will create classes that you can deserialize to the way you want.
You are missing the closing ']' so that needs to be addressed first.
If you use a dictionary and need to iterate it :
foreach(KeyValuePair<string, string> entry in myDictionary) { // do something with entry.Value or entry.Key }
I have the following JSON(modified) which is read from a HttpWebRequest response stream, and I want to extract the value of "sys_id":
{
"result": {
"number": "INC0012618",
"opened_by": {
"link": "//XXX.service-now.com/api/now/v1/table/sys_user/38723e5ddb42f200deb8f6fcbf96196d",
"value": "38723e5ddb42f200deb8f6fcbf96196d"
},
"sys_created_on": "2017-07-20 14:41:52",
"sys_domain": {
"link": "://XXX.service-now.com/api/now/v1/table/sys_user_group/global",
"value": "global"
},
"u_incident_summary": "",
"business_service": {
"link": "://xxx.service-now.com/api/now/v1/table/cmdb_ci_service/IT services",
"value": "IT services"
},
"work_end": "",
"caller_id": {
"link": "://xxxx.service-now.com/api/now/v1/table/sys_user/71f5455d4f735e000d7f0ed11310c719",
"value": "71f5455d4f735e000d7f0ed11310c719"
},
"close_code": "",
"assignment_group": {
"link": "://xxx.service-now.com/api/now/v1/table/sys_user_group/9e158987dba27a007ea0f4e9bf961983",
"value": "9e158987dba27a007ea0f4e9bf961983"
},
"sys_id": "7fb4e50edb8c0b007ea0f4e9bf9619ba",
"u_outage_start_time": ""
}
}
This is what I have tried so far, where incident_responce is a string containing the JSON above:
var jObject = JObject.Parse(incident_responce);
var value = (string)jObject["sys_id"];
Console.WriteLine(value);
But, it didn't work, I think because there is "result" at the start. How can I retrieve this value?
As you suspected, your initial attempt fails because "sys_id" is nested inside the "result" object:
{ "result": { ... "sys_id":"7fb4e50edb8c0b007ea0f4e9bf9619ba" } }
It's easier to see this if you indent and format your JSON, for instance by uploading it to https://jsonformatter.curiousconcept.com/.
Such a nested value can be queried directly by using JToken.SelectToken():
var root = JToken.Parse(incident_responce);
var value = (string)root.SelectToken("result.sys_id");
SelectToken() supports querying for values deep within the JSON container hierarchy using JSONPath syntax. If the "result.sys_id" token is not found, null is returned.
Alternatively, you could use Json.NET's support for querying JSON hierarchies using dynamic functionality:
dynamic root = JToken.Parse(incident_responce);
var value = (string)root.result.sys_id;
However, if the "result" token is not found, a RuntimeBinderException will be thrown instead of a null value returned.
Working .Net fiddle.
I am serializing data with Avro in C#.
Then i deserialize it with Python. Let's assume i have following schema:
{
"type": "record",
"name": "ClassXY",
"fields" : [{"name": "x", "type": "double"}]
}
How can i check on python-side if my record is of type "ClassXY"?
Can i get access to the value(ClassXY) of "name" somehow?
message_buf = io.BytesIO(message)
reader = avro.datafile.DataFileReader(message_buf, avro.io.DatumReader())
schema_name = reader.datum_reader.reader_schema.name
i have an object that is being passed to me from a json obj, each time it is has different feilds, i am using json.net to parse it, it is parsing it correctly and it is putting it in a list of obj
the format after serialization is:
{
"language": "EN",
"code": "test",
"name": "test",
"value": "TEST",
"id": "2222222222222222"
}
the fields are dynamic it can be up to 50 not just 5
any idea on how to parse it??
If you know the items in above format. you could create an typed object. and then you can use DataContractJsonSerializer like below.
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(List<Student>));
List<Student> result = obj.ReadObject(stream) as List<myClass>;