Convert JSON [][] to object in c# - c#

I have a little problem converting my JSON Object I have to something I can work within C# code.
{ "CheckboxHours": {
"method": "ID",
"valueparts": [
"Hour",
[ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" ]
]
}
}
This is my JSON String I have, which is for creates me the Selenium Object.
What i want is to combine the values from valueparts[0] ("Hour") with valueparts[1][0-23] with each other and create an array of Selenium Objects
var jsonData = JsonConvert.DeserializeObject<jsonc#file>(_jsonFile);
Object[] hours = (Object[])jsonData.CheckboxHours.Valueparts[1];
SeleniumCheckBox[] checkbox = new SeleniumCheckBox[hours.Length];
for (int i = 0; i < hours.Length; ++i)
{
cbHour[i] = new SeleniumCheckBox(jsonData.CheckboxHours.Valueparts[0].ToString() + hours[i]);
}
The SeleniumCheckBox is a Class I made which just takes the value and creates in the background a new Selenium Element with findElement(By.ID(value)). This is working already.
My Problem here is that he doesn't allow the Conversion from jsonData to Object[] and I don't really know how I can handle this.
I hope it is clear what I want to have - if not feel free to ask for more specific data.

I think. You can try this.
var jsonData = JsonConvert.DeserializeObject<dynamic>(_jsonFile);
var hours = jsonData.CheckboxHours.valueparts[1];
foreach (var hour in hours)
{
//Some code
}

I am not sure if I understood everything correctly, but the reason for failure in deserialization might be that valueparts is List parameter, usually in c# the Lists contain only 1 type of parameters eg. string, or int. In your case, "Hour" (valueparts[0]) is a string, and valueparts[1] is List. I assume here is the conflict with deserializing the JSON string.
{
CheckboxHours:{
"method":"ID",
"valueparts":{
Measure: "Hour",
MesureValues:
[
"0","1","2","3","4","5","6","7",
"8","9","10","11","12","13","14",
"15","16","17","18","19","20",
"21","22","23"
]
}
}
}
Change valueparts to object, as in the code above, so you can use Hour as string and the values as List.

Related

Unable to iterate Jobject when having single value

I am using for each to iterate and get values of a json object in my solution.
Let me give example of the json.
[
{
"#Seq": "1",
"#text": "123456789"
},
{
"#Seq": "2",
"#text": "abc"
},
{
"#Seq": "3",
"#text": "xyz"
}
]
It works well for multiple sequences until we have only one seq in the json.
example:
{{
"#Seq": "1",
"#text": "123456789"
}}
Coming to Code:
foreach (var installinst in atpmessage["AUTOPILOTMessage"]["AUTOPILOTBody"]["OrderHeader"]["InstallationInstructions"]["InstallationInstruction"])
{
responseISGEMEA.data.install_instruct =installinst["#text"].ToString();
}
The installinst in the loop gives me just the Seq. Not the text.
{"#Seq": "1"}
how do I make it work with single and multiple sequences.

How to access inner properties of a Json Object?

I am learning C# and I am trying to parse json/xml responses and check each and every key and value pair. For xml I am converting to json so I have only one function/script to work with both cases. My issue is that I am working with a wide range of json responses which are not similar and there may be arrays in some of the json response. I have tried accessing the "Count" of the json object as a way to check for arrays.
Note: The responses will vary. This example is for Products > Product > name, quantity and category. The next response will change and can be like Country > State > Cities and so on. I cannot rely on creating classes since all responses are going to be different. Plus I am working on automating it so it should be able to handle anything thrown at it.
Sample Json I am working with:
{
"products": {
"product": [
{
"name": "Dom quixote de La Mancha",
"quantity": "12",
"category": "Book"
},
{
"name": "Hamlet",
"quantity": "3",
"category": "Book"
},
{
"name": "War and Peace",
"quantity": "7",
"category": "Book"
},
{
"name": "Moby Dick",
"quantity": "14",
"category": "Book"
},
{
"name": "Forrest Gump",
"quantity": "16",
"category": "DVD"
}
]
}
The way I am accessing the count, name and value is as follows:
dynamic dyn = JsonConvert.DeserializeObject<dynamic>(jsonText);
foreach (JProperty property in dyn.Properties())
{
string propname = property.Name;
var propvalue = property.Value;
int count = property.Count;
}
Is there a way to access these without going through the foreach loop like int count = dyn.Count ? All I am getting from this is null instead of actual values.
For the above example my end result will be like:
This responses contains products> product> 5 x (name, quantity, category)
The QuickWatch for the object:
QuickWatch for dyn object
Try to deserialize your JSON into JObject like below:
var jObject = JsonConvert.DeserializeObject<JObject>(jsonText);

Transform json to custom json format C#

We have a json object provided by vendor with naming conventions suitable only for vendor system. We would like to rename all the json attributes names matching our company's naming standards. I showed a very small XML file but in reality we have a huge XML with many elements. The transformed json object will eventually be persisted in our datastore.Any inputs in handling efficient way?
Json Example Provided by Vendor
{
"Events": [
{
"TestOn": {
"TestCode": "32",
"TestSubCode": "11",
"TestStatus": "4",
},
"Timers": {
"TestOpCode": "10",
"TestMode": "4",
"TestItemTime": "4",
}
}
],
"Ticket": [
{
"Discount": {
"OpCode": "3",
"CluCode": "00001530020003",
"DeptNo": "11",
},
"Promotion": {
"OpCode": "96",
"SubCode": "26",
"F-Promotion": "1",
}
}
]
}
Transformed Json Object
{
"PxEvents": [
{
"PxTestOn": {
"PxTestCode": "32",
"PxTestSubCode": "11",
"PxTestStatus": "4",
},
"PxTimers": {
"PxTestOpCode": "10",
"PxTestMode": "4",
"PxTestItemTime": "4",
}
}
],
"PxTicket": [
{
"PxDiscount": {
"PxOpCode": "3",
"PxCluCode": "00001530020003",
"DeptNo": "11",
},
"PxPromotion": {
"PxOpCode": "96",
"PxSubCode": "26",
"PxPromotion": "1",
}
}
]
}

Itext Add Table Cell data downwards

I have a code like this
string[] data = new string[] { "1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14",
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14",
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14",
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14",
"1", "2", "3", "4", "5", "6", "7", "8",
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14",
"9", "10", "11", "12", "13", "14",};
using (PdfWriter writer = new PdfWriter(destinationFile))
{
// Creating a PdfDocument object
using (PdfDocument pdfDoc = new PdfDocument(writer))
{
// Creating a Document object
using (Document doc = new Document(pdfDoc))
{
// Creating a table
float[] pointColumnWidths1 = { 150f, 150f, 150f, 150f };
Table table = new Table(pointColumnWidths1);
Cell cell;
float[] pointColumnWidths2 = { 150f };
Table nestedTable = new Table(pointColumnWidths2);
for (int y = 0; y < data.Length; y++)
{
cell = new Cell();
cell.Add(data[y]);
nestedTable.AddCell(cell);
}
table.AddCell(nestedTable);
doc.Add(table);
doc.Close();
}
}
}
And this is the output
What am i doing is Populating a four table column using itext not itextsharp.
Ok the nested table is working so far. But if the data array is populated up to 100 string of array. I'm receiving an error
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.
And i assume that the error is because the populated nested table is too big for the parent table?
So how can i make it adjust that if the nested table is too big. some of the data will be written on the next column. I can't really solve the problem my self so i'm asking a question here.
Sorry for the incomplete question.
Here is the error
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Collections.Generic.List`1.set_Item(Int32 index, T value)
at iText.Layout.Renderer.TableRenderer.UpdateFirstRowBorders(Int32 colN)
at iText.Layout.Renderer.TableRenderer.CollapseAllBorders()
at iText.Layout.Renderer.TableRenderer.Layout(LayoutContext layoutContext)
at iText.Layout.Renderer.RootRenderer.AddChild(IRenderer renderer)
at iText.Layout.RootElement`1.Add(IBlockElement element)
at iText.Layout.Document.Add(IBlockElement element)
at PdfItextSample.Program.CreatePdf(String destinationFile, List`1 lst)
and it's pointing to line
doc.Add(table);
Thank you very much
I assume you use an older iText7 version (probably a 7.0.x?) because you use
string[] data = ...;
...
cell.Add(data[y]);
while Cell.Add(string) has been removed from the iText7 API nearly 2 years ago.
To make your code runnable with a current iText7, I replaced that Add call by
cell.Add(new Paragraph(data[y]));
After this simple replacement, your code ran without issue with a current iText 7.1.7 SNAPSHOT and with the 7.1.6 release.
Indeed, a lot of work has been done in particular in the table creation code. Thus, you appear to have run into a meanwhile fixed table related bug.
To continue you should update.

Serialize/Deserialize nested objects in flat structure

I'm sure that somewhere there is a simple answer to my question, but I couldn't fin it. The problem I faced is following, I have code structure:
class Field
{
List<Block> Blocks {get;set;}
public static Field CreateField()
{
var A = new Block {Connector = new Connector()}
var B = new Block {Connector = new Connector()}
A.Connector.ConnectedTo.Add(B);
B.Connector.ConnectedTo.Add(A);
var field = new Field();
field.Blocks = new List {A, B};
return field;
}
}
class Block
{
Connector Connector {get;set;}
}
class Connector
{
List<Block> ConnectedTo {get;set;}
}
Than serialization command using json.net:
JsonConvert.SerializeObject(Field.CreateField(), Formatting.Indented, new JsonSerializerSettings {PreserveReferencesHandling = PreserveReferencesHandling.Objects});
and output result is as expected:
{
"$id": "1",
"Blocks": [
{
"$id": "2",
"Connector": {
"$id": "3",
"ConnectedTo": [
{
"$id": "4",
"Connector":{
"$id": "5",
"ConnectedTo": [
{
"$ref": "2"
}
]
}
}
]
}
}
]
}
Is there any way to have serialization result as following:
{
"$id": "1",
"Blocks": [
{
"$id": "2",
"Connector": {
"$id": "3",
"ConnectedTo": [
{
"$ref": "4"
}
]
}
},
{
"$id": "4",
"Connector":{
"$id": "5",
"ConnectedTo": [
{
"$ref": "2"
}
]
}
}
]
}
Thanks.
No. In your second example, $ref : 4 points to an $id that occurs later in the JSON. Json.Net will not be able to deserialize this-- when it comes upon a $ref it expects to be able to resolve it to an $id that it has already seen.
I would recommend against requiring users modify JSON directly anyway unless they are technically savvy. As I've seen from answering many JSON-related questions on SO, it is very easy to get the format messed up if you edit it manually-- missing quotes or commas, mismatched braces, invalid syntax, you name it. What will you do when someone screws it up? I think a better option is to make a tool that allows manipulating your structure abstractly. The tool could deserialize the original JSON, allow certain changes and then reserialize it into the new structure. Users would not need to know anything about the underlying JSON format that way.

Categories