C# JsonArray to string (not string array. string only) - c#

I've been searching for this one for quite a while but can't find anything. Appologies then for the title, as there is a lot on converting content to String Arrays, which is not what I need.
I need a way to convert the contents of a JsonArray to string just as is. (Similar to JToken's .ToString()). My scenario is of such a nature that I need the string of an array just as is, irrigardless of the type/s contained within. There are ways of handling weakly typed json with ValueConverters, but I spesifically do not want to use them, as I need to pass the content of a field as a string to a Javascript Function in a WebView.
I have the following json (note markers indicating where string is desired) :
"highlights2":[
{
"_id":"highlight2-2850cb68121f9d4093e67950665c45fab02cec81",
"_rev":"9-c4345794001495104f8cbf5dd6999f3a",
"content":{ <---- Need this as string
"#roepman.17.0":[
[
233,
249,
"itsi-hl-gr"
],
[
298,
317,
"itsi-hl-bl"
]
],
"#roepman.19.0":[
[
5,
7,
"itsi-hl-gr"
]
]
}, <----- Up to here
"created":1434552587
}, //...more like this
],
"book":"book-930d62a2-9b7c-46a9-b092-f90469206900",
"serverTime":1435151280
Ideally I want to parse it into a list of the following type:
public class HighlightInfo2
{
public string _id { get; set; }
public string _rev { get; set; }}
public string content { get; set; }
public long created { get; set; }
}
However this is not possible, as the content of "content" is of type JsonArray. So to get past not having to specify a type for "content", I use this:
public class HighlightInfo2
{
public string _id { get; set; }
public string _rev { get; set; }}
public Dictionary<string, List<JsonArray>> content { get; set; }
public long created { get; set; }
}
But this means I still have to at some point convert the List< JsonArray > inside the dictionary to a string as I pass the content of "content" to a Javascript function in a webview later on.
Any way of converting the JsonArray to a string?

Based on your comment, the formatting of that string is irrelevant. It just has to be valid JSON representing the original data.
What I would suggest then is to make your content member in HighlightInfo2 of type object and simple perform a JsonConvert.SerializeObject(highlightInfo.content) to get the JSON string. This is what you can then pass over to the JavaScript function.
If you need to do this often, you can combine this with Behzad's answer and add another member to your class that stores this converted value.

What i suggest is to make another property like contentJson under highlightInfo2 class and put the string of jsonarray in it.
public class HighlightInfo2
{
private Dictionary<string, List<JsonArray>> _content;
public string _id { get; set; }
public string _rev { get; set; }
public Dictionary<string, List<JsonArray>> content
{
get { return _content; }
set
{
_content = value;
foreach (var item in _content)
{
contentJson += string.Join("\r\n", item.Value);
}
}
}
[JsonIgnore] //note, this depends on your json serializer
public string contentJson { set; get; }
public long created { get; set; }
}

Using a combination of Daniel's Answer and Behzad's Answer, I came up with this class/type for deserialization, which works without a hitch. Thanks for the help.
public class HighlightInfo2
{
public string _id { get; set; }
public string _rev { get; set; }
public long created { get; set; }
private JToken _content { get; set; }
public JToken content
{
get { return _content; }
set
{
_content = value;
contentString = JsonConvert.SerializeObject(value);
}
}
[JsonIgnore]
public string contentString { get; set; }
}

Related

Read JSON Array that contains Arrays(?) C#

I apologize in advance for the poor explanation of my problem.
I'm trying to read a JSON array that contains data.
Here's how the JSON looks:
{
"playerstats": {
"steamID": "76561198071680006",
"gameName": "GameName",
"achievements": [
{
"apiname": "AchievementName1",
"achieved": 0, <--- Data that I want to read
"unlocktime": 0
},
{
"apiname": "AchievementName2",
"achieved": 0, <--- Data that I want to read
"unlocktime": 0
},
{
"apiname": "AchievementName2",
"achieved": 1, <--- Data that I want to read
"unlocktime": 1477847680
}
]
,
"success": true
}
}
I'm trying to look at Newtonsoft.Json and how to use that yet I'm at a complete loss as to how to use this. Any help would be appreciated.
You can try JsonConvert.DeserializeObject to read json data.
Having
public class Rootobject
{
public Playerstats playerstats { get; set; }
}
public class Playerstats
{
public string steamID { get; set; }
public string gameName { get; set; }
public Achievement[] achievements { get; set; }
public bool success { get; set; }
}
public class Achievement
{
public string apiname { get; set; }
public int achieved { get; set; }
public int unlocktime { get; set; }
}
You can try this:
var filePath = path to your file;
var jsonData = System.IO.File.ReadAllText(filePath);
Rootobject objectValue =
Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(jsonData);
Note: you should remove <--- Data that I want to read parts from your json data because currently it is not a valid json format.
You may access to your desired properties like this
objectValue.playerstats.achievements[0].achieved //0
objectValue.playerstats.achievements[1].achieved //0
objectValue.playerstats.achievements[2].achieved //1

Parse complex JSON: multiple loops vs. classes

I have a Json of type :
{
"JobProcessors": [
{
"JobName": "ArchivalJob",
"IsEnabled": true,
"Batching": {
"BatchSize": 0,
"DegreeOfParallelism": -1
},
"Settings": {
"ArchivalJobCollectionPageSize": 50
}
},
{
"JobName": "AuditLogJob",
"IsEnabled": false,
"Batching": {
"BatchSize": 10,
"DegreeOfParallelism": -1
},
"Settings": {}
}
],
"ScheduledJobs": [
{
"JobName": "RemoteStartClientCommandJob",
"PrimaryAction": {
"ConnectionString": "#JobProcessorsIntegrationSBConnectionStringValue#",
"Settings": {
"LeadTimeInSeconds": "600",
"MaxSrsJobCount": 25
}
},
"ErrorAction": {
"ConnectionString": "#PairedJobProcessorIntegrationSBConnectionStringValue#",
"EntityPath": "remotestartqueue",
"Settings": {
"LeadTimeInSeconds": "600",
"MaxSrsJobCount": 25
}
}
}
]
}
I want to check the "IsEnabled" property for all "JobName" for which come under "JobProcessors" category.
In C# what i Have used till now is :
dynamic parsedJson = JsonConvert.DeserializeObject(reader.GetString(1));
foreach (var item in parsedJson)
{
foreach (var smallitem in item)
{
foreach (var tag in smallitem)
{
if(tag.IsEnabled.toString()=="true"){
Console.WriteLine("true");
}
}
}
}
This is giving me correct result except the fact that it also iterates for "ScheduledJobs" . But the main issue is :
Is this the right or most efficient way to do this ? If possible suggest some better method .
One that i know of is using classes , but i may not know the json structure beforehand. Also the json is very huge so making classes can be cumbersome !!
Given that you are already doing JObject.Parse(jsonstring); to parse your JSON string, you can use SelectTokens() with a JSONPath query to find all "JobName" objects under "JobProcessors":
// I want to check the "IsEnabled" property for all "JobName" for which come under "JobProcessors"
foreach (var job in root.SelectTokens("..JobProcessors[?(#.JobName)]"))
{
var isEnabled = (bool?)job["IsEnabled"];
Debug.WriteLine(string.Format("Job {0}: IsEnabled={1}", job["JobName"], isEnabled));
}
Notes:
.. is the recursive descent operator: it recursively descends the JToken hierarchy returning each item, subsequently to be matched against the remaining parts of the query string.
JobProcessors returns values of properties of that name.
[?(#.JobName)] returns array items (of JobProcessors in this case) that are objects with a JobName property.
(bool?) casts the value of "IsEnabled" to a boolean or null if missing.
And the output of this is:
Job ArchivalJob: IsEnabled=True
Job AuditLogJob: IsEnabled=False
As in your code snippet we are using two foreach it may take time for large object. So we can do the same thing in a single foreach or if you have some specific node to fetch or search we can use linq, and for this first we need to convert our json object into c# object. For converting Json object to C# you can use this site "http://json2csharp.com/" then we can Deserialize Json object into c#.
It will be something like this
string jsonString = "your Json Object as string";
var jsonObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
foreach (JobProcessor obj in jsonObject.JobProcessors)
{
string JobName = obj.JobName;
bool value=obj.IsEnabled;
}
And I also converted given Json in c# object if the Json object is same you can directly use these classes.
public class Batching
{
public int BatchSize { get; set; }
public int DegreeOfParallelism { get; set; }
}
public class Settings
{
public int ArchivalJobCollectionPageSize { get; set; }
}
public class JobProcessor
{
public string JobName { get; set; }
public bool IsEnabled { get; set; }
public Batching Batching { get; set; }
public Settings Settings { get; set; }
}
public class Settings2
{
public string LeadTimeInSeconds { get; set; }
public int MaxSrsJobCount { get; set; }
}
public class PrimaryAction
{
public string ConnectionString { get; set; }
public Settings2 Settings { get; set; }
}
public class Settings3
{
public string LeadTimeInSeconds { get; set; }
public int MaxSrsJobCount { get; set; }
}
public class ErrorAction
{
public string ConnectionString { get; set; }
public string EntityPath { get; set; }
public Settings3 Settings { get; set; }
}
public class ScheduledJob
{
public string JobName { get; set; }
public PrimaryAction PrimaryAction { get; set; }
public ErrorAction ErrorAction { get; set; }
}
public class RootObject
{
public List<JobProcessor> JobProcessors { get; set; }
public List<ScheduledJob> ScheduledJobs { get; set; }
}
Hope this will help.
Thank you

Using JSON.net define class with array in Dictionary

I am trying to do the following inside a Dictionary<string,string>
{
"name": "Bob Barker",
"devName": "InformationServices",
"ReturnedData": [{
"level_heading": "blah1",
"DeliverBestMedicalValue": "blah2",
"level_question": "blah3"
}]
}
I can add the name and devName just fine but I am unsure on how to go about adding the ReturnedData part of the array to the list so that it will return as the layout above?
Example code I am using:
febRecords.RootObject febRecordsData = JsonConvert.DeserializeObject<febRecords.RootObject>(serverResponse);
Dictionary<string,string> febFormData = new Dictionary<string,string>();
febFormData.Add("name", data.firstname.ToString());
febFormData.Add("devName", febData["Data"]["DevisionName"].ToString());
febFormData.Add("ReturnedData", ???); //<-this is where I am stuck
return Ok(JsonConvert.SerializeObject(febFormData, Newtonsoft.Json.Formatting.Indented));
As you see, febFormData.Add("ReturnedData", ???); is the spot where I am stuck and dont really know what to do in order to get the dictionary to output the correct JSON format like I want.
Any help would be great!
update
Would this be how the class needs to look?
public class theOutput
{
public string name { get; set; }
public string devName { get; set; }
public List<string> ReturnedData { get; set; }
}
As suggested by #Panagiotis Kanavos you'd really be better off having .NET entity to match your JSON data. For example:
// propertyname attributes can be ignored if property names
// match the json data property names 1:1
[JsonObject]
public class MyClass
{
public MyClass()
{
ReturnedData = new List<ReturnedData>();
}
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "devName")]
public string DevName { get; set; }
[JsonProperty(PropertyName = "ReturnedData")]
public List<ReturnedData> ReturnedData { get; set; }
}
[JsonObject]
public class ReturnedData
{
[JsonProperty(PropertyName = "level_heading")]
public string LevelHeading { get; set; }
[JsonProperty(PropertyName = "DeliverBestMedicalValue")]
public string DeliverBestMedicalValue { get; set; }
[JsonProperty(PropertyName = "level_question")]
public string LevelQuestion { get; set; }
}
This would make conversion to/from JSON that much easier.
[TestMethod]
public void TestSome()
{
string json = #"{
""name"": ""Bob Barker"",
""devName"": ""InformationServices"",
""ReturnedData"": [{
""level_heading"": ""blah1"",
""DeliverBestMedicalValue"": ""blah2"",
""level_question"": ""blah3""
}]
}";
var obj = JsonConvert.DeserializeObject<MyClass>(json);
Assert.IsTrue(JToken.DeepEquals(JObject.Parse(json), JObject.FromObject(obj)));
}
You can always generate stubs from you JSON data using e.g. http://json2csharp.com/
Here "live" .NET fiddle, too https://dotnetfiddle.net/9ACddp

C# convert string to dictionary

I get this response string from the Bitly api:
{ "status_code": 200,
"status_txt": "OK",
"data":
{ "long_url": "http:\/\/amazon.de\/",
"url": "http:\/\/amzn.to\/1mP2o58",
"hash": "1mP2o58",
"global_hash": "OjQAE",
"new_hash": 0
}
}
How do I convert this string to a dictionary and how do I access the value for the key "url" (without all the \)
This isn't just some ordinary string. This is a data structure in JSON format, a common and well-established format, originally used in Javascript but now rather common as a data transfer mechanism between services and clients.
Rather than reinventing the wheel and parsing the JSON yourself, I suggest you use an existing JSON library for C#, such as JSON.NET, which will eat up that string and parse it into .NET objects for you.
Here's a code sample, taken from JSON.NET's documentation, showing its usage:
string json = #"{
'href': '/account/login.aspx',
'target': '_blank'
}";
Dictionary<string, string> htmlAttributes =
JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(htmlAttributes["href"]);
// /account/login.aspx
Console.WriteLine(htmlAttributes["target"]);
// _blank
If you add a package like Newtonsoft's Json to your project, you can deserialize the Json in to an anonymous type. You can then fetch the url from that. This is available via NuGet within Visual Studio and provides support for async or sync serialization/deserialization.
public string GetUrl(string bitlyResponse)
{
var responseObject = new
{
data = new { url = string.Empty },
};
responseObject = JsonConvert.DeserializeAnonymousType(bitlyResponse, responseObject);
return responseObject.data.url;
}
I'd use JSON.NET.
http://james.newtonking.com/json
MIT License which means if you're doing anything commercial you are good.
I don't think you would want to go straight to a Dictionary, because there is some stuff there that isn't a one to one relationship. So you could make a class like the following.
public class BitlyData
{
public string LongUrl{ get; set; }
public string Url { get; set; }
public string Hash { get; set; }
public string GlobalHash { get; set; }
public string NewHash { get; set; }
}
You could then use Json.NET to turn that String into an JObject. So we'll call your string bitlyString.
JObject bitlyObject = JObject.Parse(bitlyString);
Now we have that all that is left to do is access the data.
BitlyData theData = JsonConvert.DeserializeObject<BitlyData>(bitlyObject["data"]);
Then you can access the url (and any other pieces) using the getters.
Of course you could make it even better by having class that handles the other bits as well so you just do one serialisation.
1)Add these classes to your project
public class Rootobject
{
public int status_code { get; set; }
public string status_txt { get; set; }
public Data data { get; set; }
}
public class Data
{
public string long_url { get; set; }
public string url { get; set; }
public string hash { get; set; }
public string global_hash { get; set; }
public int new_hash { get; set; }
}
2)Add a reference to JSON.NET
3)
string jsonString= "YOUR JSON STRING";
Rootobject weps = JsonConvert.DeserializeObject<Rootobject>(jsonString);
Console.WriteLine(weps.status_code);
if (weps.data != null)
{
Console.WriteLine(weps.data.url);
Console.WriteLine(weps.data.global_hash);
//...
}

nested json c# object deserialization

i have the following json string (jsonString)
[
{
"name":"Fruits",
"references":[
{"stream":{"type":"reference","size":"original",id":"1"}},
],
"arts":[
{"stream":{"type":"art","size":"original","id":"4"}},
{"stream":{"type":"art","size":"medium","id":"9"}},
]
}
]
and the following C# objects
class Item
{
public string Name { get; set; }
public List<Stream> References { get; set; }
public List<Stream> Arts { get; set; }
public Item()
{
}
}
class Stream
{
public string Type { get; set; }
public string Size { get; set; }
public string Id { get; set; }
public Stream()
{
}
}
and the following code
Item item = JsonConvert.DeserializeObject<Item>(jsonString);
when I run the code, it creteas the correct number of references and arts, but each stream has null value (type = null, size = null).
is it posible to do this json.net deserializeobject method or should I manually deserialize ?
EDIT: Okay, ignore the previous answer. The problem is that your arrays (references and arts) contain objects which in turn contain the relevant data. Basically you've got one layer of wrapping too many. For example, this JSON works fine:
[
{
"name":"Fruits",
"references":[
{"Type":"reference","Size":"original","Id":"1"},
],
"arts":[
{"Type":"art","Size":"original","id":"4"},
{"type":"art","size":"medium","id":"9"},
]
}
]
If you can't change the JSON, you may need to introduce a new wrapper type into your object model:
public class StreamWrapper
{
public Stream Stream { get; set; }
}
Then make your Item class have List<StreamWrapper> variables instead of List<Stream>. Does that help?

Categories

Resources