I have a json property like "A\/B" and I want to deserialize it in c# property AB
I have tried both System.Text.Json and
[JsonPropertyName(#"A\/B")]
public bool AB { get; set; }
Or
[JsonProperty(#"A\/B")]
public bool AB { get; set; }
Or
[JsonProperty(PropertyName = (#"A\/B")]
public bool AB { get; set; }
or
[JsonPropertyName("A\\/B")]
public bool? AB { get; set; }
but is not deserialized correctly is always false and in the json file is true like "A/B": true,.
Json example :
{
"List": [
{
"Name": "name",
"A\/B": true,
},
{
"Name": "name1",
"A\/B": false,
}
]
}
Any suggestions will be highly appreciated.
If the JSON looks like
{
"A\/B": true
}
Then the name of the property is actually just A/B.
The backslash character also acts as an escape character in JSON syntax, so the backslash isn't actually part of the property name. Even though the forward slash doesn't need any escaping in this case, it is still acceptable to escape it nonetheless. See RFC 8259 section 7.
So, in your C# code, you also don't need any backslashes:
[JsonProperty("A/B")]
or
[JsonPropertyName("A/B")]
depending on whether you are using Json.NET or System.Text.Json.
Related
This is the JSON object I am receiving from a GET request:
{
"data": {
"valve_maker": [],
"water_volume": [
"15L",
"20L",
"..."
],
"cylinder_manufacturer": [
"Tianhai"
],
"qc_stamp": [
"TS"
],
"reference_standard": [
"GB 5099"
],
"production_licence": [
"TS2210752-2016"
],
"valve_production_licence": [
"TSF210030"
],
"rate_of_residual_deformation": {
"1": "<3%",
"2": "<10%"
},
"material_number": {
"1": "30CrMo",
"2": "34CrMo4",
"3": "..."
},
"heat_treatment": {
"1": "...",
"2": "..."
},
"drawing_number": {
"1": "...",
"2": "..."
},
"cylinder_thickness": []
}
right now, I am able to parse JSON objects with a simpler structure like :
{
"data": [
{
"gas_id": "ID of the gas",
"gas_name": "Gas name"
}
]
by using something like this:
private void jsonparsegas(string res)
{
JObject par = JObject.Parse(res);
foreach (JToken data in par["data"].Children())
{
string id = data["gas_id"].ToString();
string name = data["gas_name"].ToString();
if (this.cmbCylType.Items.Contains(name) == false)
{
this.cmbCylType.Items.Add(name);
}
}
}
When I try to apply the same thing to the more complicated JSON object, I get an error:
private void jsonparsecoc(string res)
{
//JObject par = JObject.Parse(res);
var jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(res);
foreach (var child in jObj["data"].Children())
{
string vMaker = child["valve_maker"].ToString(); //error thrown here right away
string wVolume = child["water_volume"].ToString();
string cMan = child["cylinder_manufacturer"].ToString();
string QC = child["qc_stamp"].ToString();
string rStandard = child["reference_standard"].ToString();
string pLicence = child["production_licence"].ToString();
string VPL = child["valve_production_licence"].ToString();
string rrd = child["rate_of_residual_deformation"].ToString();
string mNum = child["material_number"].ToString();
string hTreatment = child["heat_treatment"].ToString();
string dNum = child["drawing_number"].ToString();
string cThick = child["cylinder_thickness"].ToString();
}
Cannot access child value on Newtonsoft.Json.Linq.JProperty
I have tried a few different things I found on StackOverflow, but I don't really understand how Deserializing of the objects works. The simpler parsing works just fine, and allows me to add all "gas_name"s that I receive from my GET request to a combobox. The format the first "valve_maker" child of "data" seems to have the same structure as "gas_id" or "gas_name" in the more similar JSON object, but this is where I receive the error right away. If I had to guess at a cause for the error, I'd say it has something to do with the difference between using
"valve_maker": []
and using
"gas_id": "ID of the gas"
in the objects. also I notice "data" is followed by [] brackets in the simpler one, and {} in the more complicated one.
If anyone could link to some good reading material, or offer a good explanation of a solution/what's going on, I'd really appreciate it.
This part is the key to the problem you're having:
in the objects. also I notice "data" is followed by [] brackets in the simpler one, and {} in the more complicated one.
In JSON,
[] brackets enclose an array
{} brackets enclose an object
In both code examples, you are digging into the object by looping through the results using par["data"].Children(). To be consistent with the JSON model, JSON.NET defines different behavior for resolving children of objects and arrays. The children of an object are its properties and the children of an array are its items.
In your code, the input to jsonparsegas is an array of simple objects with 2 properties where the input to jsonparsecoc is a single complex objects with many properties.
In jsonparsegas, the Children() call gives you an array of all the simple gas objects. You loop through these objects and extract the values of "gas_id" and "gas_name" for each object. In your example data, there only happens to be one gas object so your code only executes once.
In jsonparsecoc, the Children() call actually gives you property values for the properties of the complex object, since the result is an object and not an array. So, when you loop through this result you can't access things like "valve_maker", because they are defined on the complex object and you have already stepped into the value for valve_maker then this executes.
The solution is simple. Don't loop through the properties in jsonparsecoc. Instead of foreach(var child in jObj["data"].Children()) you need something like var child = jObj["data"];. This will give you the reference to the object that actually contains each of the properties you are trying to access.
#smartcaveman did a good job of explaining what is going wrong with your code. However, you might find your data a little easier to process if you defined strongly-typed classes for it like this:
class RootObject
{
public Data Data { get; set; }
}
class Data
{
[JsonProperty("valve_maker")]
public List<string> ValveMaker { get; set; }
[JsonProperty("water_volume")]
public List<string> WaterVolume { get; set; }
[JsonProperty("cylinder_manufacturer")]
public List<string> CylinderManufacturer { get; set; }
[JsonProperty("qc_stamp")]
public List<string> QCStamp { get; set; }
[JsonProperty("reference_standard")]
public List<string> ReferenceStandard { get; set; }
[JsonProperty("production_licence")]
public List<string> ProductionLicense { get; set; }
[JsonProperty("valve_production_licence")]
public List<string> ValveProductionLicense { get; set; }
[JsonProperty("rate_of_residual_deformation")]
public Dictionary<string, string> RateOfResidualDeformation { get; set; }
[JsonProperty("material_number")]
public Dictionary<string, string> MaterialNumber { get; set; }
[JsonProperty("heat_treatment")]
public Dictionary<string, string> HeatTreatment { get; set; }
[JsonProperty("drawing_number")]
public Dictionary<string, string> DrawingNumber { get; set; }
[JsonProperty("cylinder_thickness")]
public List<string> CylinderThickness { get; set; }
}
You can deserialize the JSON to your classes like this:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
Demo here: https://dotnetfiddle.net/p0D7ze
public class Test{
public Data data{get;set;}
}
public class Data{
public List<string> Value_maker{get;set;}
public List<String> Water_Volume{get;set;}
public List<String> cylinder_manufacturer{get;set;}
}
Create Class structure Like that and after that use to deserialize
Jsonconvert.DeserializeObject(JsonString)
it will convert json into proper object, keep in mind structure should be proper and property name should be same as your json property
Hope It will Help you
JSON data looks like this
[
{
"market_id": "21",
"coin": "DarkCoin",
"code": "DRK",
"exchange": "BTC",
"last_price": "0.01777975",
"yesterday_price": "0.01770278",
"change": "+0.43",
"24hhigh": "0.01800280",
"24hlow": "0.01752015",
"24hvol": "404.202",
"top_bid": "0.01777975",
"top_ask": "0.01790000"
}
]
Notice these 3 properties here 24high, 24hhlow, and 24hvol
how do you make a class for that. I need all those properties by the way, not just those 3 properties I mentioned.
You should use JSON.NET or similar library that offers some more advanced options of deserialization. With JSON.NET all you need is adding JsonProperty attribute and specify its custom name that appears in resulting JSON. Here is the example:
public class MyClass
{
[JsonProperty(PropertyName = "24hhigh")]
public string Highest { get; set; }
...
Now to deserialize:
string jsonData = ...
MyClass deserializedMyClass = JsonConvert.DeserializeObject<MyClass>(jsonData);
For .NET Core 3.0 and beyond, you can now use the System.Text.Json namespace. If you are using this:
public class MyClass
{
...
[JsonPropertyName("24hhigh")]
public string twentyFourhhigh { get; set; }
...
}
You can use JsonPropertyName Attribute.
I am new to json,I am trying to convert json response to object
the json is
"[{\"fields\":[[\"name\",\"value\",\"values\",\"error\"],[\"username\",\"test\",null,\"\"],[\"password\",\"test\",null,\"\"],[\"accountid\",\"\",null,\"\"],[\"rememberMe\",\"Y\",null,\"\"],[\"language\",\"en-US\",null,\"\"],[\"S\",\"test\",null,null]],\"success\":\"Y\",\"message\":\"User authenticated. Logging in.\"}]"
I wrote two classes
public class fields
{
public string name { get; set; }
public string value { get; set; }
public string values { get; set; }
public string error { get; set; }
}
public class Demo
{
public List<fields> fields { get; set; }
public string message { get; set; }
public string success { get; set; }
}
I made this Serialize code:
JsonSerializer serializer = new JsonSerializer();
Demo result = JsonConvert.DeserializeObject<Demo>(responseFromServer);
or this
Demo result = new JavaScriptSerializer().Deserialize<Demo>(responseFromServer);
the error is
Type '_Default+fields' is not supported for deserialization of an array
Thanks
Baaroz
I tried your code and it was a bit inconclusive for me. But I can show you what i've found and you can try working from here:
First: As I commented on your question, the first and last character of your string are [ and ]. That means your server is sending you an array. To solve that, i just changed your deserialization line to this:
Demo[] result = new JavaScriptSerializer().Deserialize<Demo[]>(responseFromServer);
Second: The code was still having troubles to deserialize to your fields object, then I realized you were receiving an array of an array of strings, then I changed your property in the Demo class to this:
public string[][] fields { get; set; }
Hope this can help.
If you format your json string you will notice that each entry in fields contains another four entries, therefore List<fields> fields will not suffice.
Replace it with List<List<string>> fields instead.
It is an issue with the Json not being a match with the objects you have.
If you want the JSON to match your C# models it would look like this:
[
{
"fields": [
{
"name": "Jeff",
"value": "xcv",
"values": "xcv",
"error": "xcv"
},
{
"name": "Jeff",
"value": "xcv",
"values": null,
"error": null
}
],
"success": "Y",
"message": "Userauthenticated.Loggingin."
}
]
try using this site (there are many more like it) to play about with your C# & JSON till you get what you are after: http://json2csharp.com/
I'm pretty convinced Newtonsoft is literally the best possible way to do anything with JSON in C# and without any headaches, it's the most popular C# NuGet package in the world with almost 1 billion downloads, works in ALL .NET versions basically.
I work with JSON and Web-based APIs regularly and will never use anything else in C# to handle JSON conversions.
Here's one of the simplest examples
string json_string = #"{
Firstname: ""Jane"",
Lastname: ""Doe"",
Age: 36,
IsEmployed: true,
IsMarried: true,
Children: 4
}";
var person = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json_string);
Console.WriteLine(person.Forename);
Console.WriteLine(person.Lastname);
Console.WriteLine(person.Age);
Console.WriteLine(person.IsEmployed);
Console.WriteLine(person.IsMarried);
Console.WriteLine(person.Children);
It generates objects on the fly, no matter the structure! Other solutions don't work in all .NET versions.
I wrote a simple, easy-to-follow article here https://turmanauli.medium.com/a-complete-guide-for-serializing-json-to-dynamic-objects-on-the-fly-in-c-7ab4799f648d
about how to install and use Newtonsoft via NuGet Package Manager in your Visual Studio project.
How do I deserialize the following JSON with Web API (JSON.Net)?:
{
"action": "edit",
"table": "MainView",
"id": "row_1377",
"_group_id": "999",
"data": {
"ROTATION": "1", // This name/val can change
"EQUIPMENT": [{
"id": "6"
},
{
"id": "8"
}],
"NOTES": ""
}
}
The values in data represent columns and can change, so I can't make a set-in-stone object with e.g. a string named "NOTES" as in json.net deserialize string to nested class.
Notice EQUIPMENT contains multiple values. When it was previously just a "string:string" like NOTES, this JSON deserialized data into a Dictionary<string, string>, but now I need it to behave like its own dictionary. My last attempt was to deserialize into the following type:
public class EditorSubmissionJoined
{
public string _group_id { get; set; }
public string action { get; set; }
public string table { get; set; }
public string id { get; set; }
// "public" added below due to mistake noticed by Maggie Ying
public Dictionary<string, object> data { get; set; } // Trouble
}
I was hoping that the object could contain anything in data whether a KeyValuePair (like NOTES) or a dictionary (like EQUIPMENT).
I've also tried Dictionary<string, ICollection<Object>>, Object, and even ICollection<Dictionary<string, Object>>.
The problem is that my controller always gets EditorSubmissionJoined with nothing but null values:
public void Put(EditorSubmissionJoined ajaxSubmission) {
// ajaxSubmission has only NULL values
}
Try setting your 'data' property to public and your JSON should be able to model bind correctly.
There's a few ways you can do it. One way is to simply use a JObject and access the fields by name e.g. : jsonObject["data"]["ROTATION"]. You can "deserialize" that with JObject.Parse and just "parse" the JSON text into a JObject.
Alternatively you can write your own JsonConverter and tell JSON.net to use that converter when deserializing a specific type (e.g. JsonConverterAttribute). This requires parsing parts of the JSON text manually, in the ReadJson override, and really depends on what data you expect.
You can also use the dynamic approach that Preston commented on.
Which approach you pick depends on how strongly-typed you want things to be.
Finding some difficulty in sourcing information in trying to deserialize JSON in C#.
I have results from Google custom search returned in JSON format. I just want to check through my steps and establish the order in trying to deserialize it. Is this right?
I need to create classes to match
the JSON format. Kind of like a
creating schema file.
Use the JavaScriptSerializer() class and
deserialize method to extract the
relevant bits.
One of the issues I think I am going to run into is that I don't require all of the data returned but only the html links. How can I achieve that?
UPDATE
I have updated my question with the following JSON snippet and C# code. I want to output the string 'links' to console but it doesn't seem to be working. I think I am defining my classes wrongly?
JSON from Google Custom Search
handleResponse({
"kind": "customsearch#search",
"url": {
"type": "application/json",
"template": "https://www.googleapis.com/customsearch/v1?q\u003d{searchTerms}&num\u003d{count?}&start\u003d{startIndex?}&hr\u003d{language?}&safe\u003d{safe?}&cx\u003d{cx?}&cref\u003d{cref?}&sort\u003d{sort?}&alt\u003djson"
},
"queries": {
"nextPage": [
{
"title": "Google Custom Search - lectures",
"totalResults": 9590000,
"searchTerms": "lectures",
"count": 1,
"startIndex": 2,
"inputEncoding": "utf8",
"outputEncoding": "utf8",
"cx": "017576662512468239146:omuauf_lfve"
}
],
"request": [
{
"title": "Google Custom Search - lectures",
"totalResults": 9590000,
"searchTerms": "lectures",
"count": 1,
"startIndex": 1,
"inputEncoding": "utf8",
"outputEncoding": "utf8",
"cx": "017576662512468239146:omuauf_lfve"
}
]
},
"context": {
"title": "Curriculum",
"facets": [
[
{
"label": "lectures",
"anchor": "Lectures"
}
],
[
{
"label": "assignments",
"anchor": "Assignments"
}
],
[
{
"label": "reference",
"anchor": "Reference"
}
]
]
},
"items": [
{
"kind": "customsearch#result",
"title": "EE364a: Lecture Videos",
"htmlTitle": "EE364a: \u003cb\u003eLecture\u003c/b\u003e Videos",
"link": "http://www.stanford.edu/class/ee364a/videos.html",
"displayLink": "www.stanford.edu",
"snippet": "Apr 7, 2010 ... Course materials. Lecture slides · Lecture videos (2008) · Review sessions. Assignments. Homework · Reading. Exams. Final exam ...",
"htmlSnippet": "Apr 7, 2010 \u003cb\u003e...\u003c/b\u003e Course materials. \u003cb\u003eLecture\u003c/b\u003e slides · \u003cb\u003eLecture\u003c/b\u003e videos (2008) · Review sessions. \u003cbr\u003e Assignments. Homework · Reading. Exams. Final exam \u003cb\u003e...\u003c/b\u003e",
"cacheid": "TxVqFzFZLOsJ"
}
]
}
);
C# Snippet
public class GoogleSearchResults
{
public string link { get; set; }
}
public class Program
{
static void Main(string[] args)
{
//input search term
Console.WriteLine("What is your search query?:");
string searchTerm = Console.ReadLine();
//concantenate the strings using + symbol to make it URL friendly for google
string searchTermFormat = searchTerm.Replace(" ", "+");
//create a new instance of Webclient and use DownloadString method from the Webclient class to extract download html
WebClient client = new WebClient();
string Json = client.DownloadString("https://www.googleapis.com/customsearch/v1?key=My Key&cx=My CX&q=" + searchTermFormat);
//create a new instance of JavaScriptSerializer and deserialise the desired content
JavaScriptSerializer js = new JavaScriptSerializer();
GoogleSearchResults results = js.Deserialize<GoogleSearchResults>(Json);
Console.WriteLine(results);
//Console.WriteLine(htmlDoc);
Console.ReadLine();
}
}
Thanks
I use your #2 approach: deserialize with the JavaScriptSerializer.
This is what I do to deserialize a response from Facebook:
// get the id for the uploaded photo
var jss = new JavaScriptSerializer();
var resource = jss.Deserialize<Facebook.Data.Resource>(responseText);
....where Facebook.Data.Resource is defined like this:
namespace Facebook.Data
{
public class Resource
{
public string id { get; set; }
}
}
The responseText that I am deserializing from looks like this:
{"id":"10150111918987952",
"from":{"name":"Someone",
"id":"782272221"},
"name":"uploaded from Cropper. (at 12\/15\/2010 7:06:41 AM)",
"picture":"http:\/\/photos-f.ak.fbcdn.net\/hphotos-ak-snc4\/hs817.snc4\/69790_101501113333332_782377951_7551951_8193638_s.jpg",
...
But since I have only one property defined in the Resource class, I only deserialize that. Define the fields in your class that you want to deserialize.
It works to use inheritance, of course. You can define your data classes like this:
namespace Facebook.Data
{
public class Resource
{
public string id { get; set; }
}
public class Person : Resource
{
public string name { get; set; }
}
}
...and then you can deserialize a Person object.
EDIT
Ok, given the sample json you provided in the updated question, here's how I wrote the classes to hold the response:
public class GoogleSearchItem
{
public string kind { get; set; }
public string title { get; set; }
public string link { get; set; }
public string displayLink { get; set; }
// and so on... add more properties here if you want
// to deserialize them
}
public class SourceUrl
{
public string type { get; set; }
public string template { get; set; }
}
public class GoogleSearchResults
{
public string kind { get; set; }
public SourceUrl url { get; set; }
public GoogleSearchItem[] items { get; set; }
// and so on... add more properties here if you want to
// deserialize them
}
And here's the C# code to deserialize:
// create a new instance of JavaScriptSerializer
JavaScriptSerializer s1 = new JavaScriptSerializer();
// deserialise the received response
GoogleSearchResults results = s1.Deserialize<GoogleSearchResults>(json);
Console.WriteLine(s1.Serialize(results));
Some comments:
The toplevel class to hold the search result is called GoogleSearchResults.
The first property in the GoogleSearchResults class is kind, corresponding to the first named property in the json object. You had link which isn't going to work, because link is not the name of a top-level property in that json object. There are properties lower in the hierarchy of your json named "link" but JavaScriptSerializer won't pull out those lower level things into the higher level.
The next property in my GoogleSearchResults class is of type SourceUrl. This is because the url property in the json is not a simple string - it is a json object with two properties, each with a string value. So SourceUrl as a class in C# gets two string properties, each with the appropriate name to deserialize one of those named properties.
the next property in the GoogleSearchResults class is called "items" so that it can deserialize the items dictionary from your json. Now items, as the name suggests, is an array in the json, as denoted by the square bracket around its value. This means there can be more than one item, although in your case there is just one item. So this property in C# must be an array (or collection). Each item in the json result is not a simple string, so, once again, as we did with SourceUrl, we need to define a holder class to deserialize the item object: GoogleSearchItem. This class has a bunch of simple string properties. The properties in the C# class could also be of type int or some other type, if that's what the json requires.
finally, when printing out the result, if you just call Console.WriteLine(result) you will see the result of the ToString() method that is implicitly invoked by Console.WriteLine. This will merely print the name of the type, in this case is "GoogleSearchResults", which is not what you want, I think. In order to see what's in the object, you need to serialize it, as I've shown. In the output of that, you will see only the values of things you deserialized. Using the classes I provided, the result will have less information than the original, because I didn't provide properties in the C# class corresponding to some of the json properties, so those weren't deserialized.
You could take a look at Json.NET and its LINQ support to create and query JSON. By crafting a nice LINQ query you will get only the stuff you need (you can select, group by, count, min, max, whatever you like).
http://msdn.microsoft.com/en-us/library/bb412170.aspx
http://msdn.microsoft.com/en-us/library/bb410770.aspx
Pull out the property you need after you have converted the JSON representation to a type in your C# app. I don't think there's a way to extract only one property from the JSON representation before you have converted it (though I am not sure).