i am trying to deserialize a JSON-Object which looks quite similiar to an Array.
Here's the JSON-String:
...,"Test":[[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]],...
I do not want to deserialize it as 2D Array, because each of these values have an explicit meaning to me. I would like to access it like this:
Test[0].Example (0)
Test[0].Êxample2 (1)
Test[0].Example3 (2)
...
Test[2].Example (10)
I hope you got the idea and have a solution to my Problem.
I am using the Newtonsoft JSON Library together with C#.
EDIT1:
Maybe i should be more specific of how deserilisation is done until now:
JSON:"Object":{"A":0,"Test":[[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]],"B":1,...}
C#:
m_Object = JsonConvert.DeserializeObject<Object>(jsonString);
The Class Object is defined in C# containing all the fields of the JSON-String.
Object-Class:
class Object
{
public Int32 A {get;set;}
public Object Test {get;set;}
public Int32 B {get;set;}
}
You can use LINQ to JSON:
string json = "[[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]]";
var tests = JsonConvert.DeserializeObject<JArray>(json)
.Cast<JArray>()
.Select(a => new Test {
Example = (int)a[0],
Example2 = (int)a[1]
// etc
});
Result:
UPDATE: For your updated question - you can deserialize json object, and then access its properties by their keys
string json = #"{'A':0,'Test':[[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]],'B':1}";
var obj = JsonConvert.DeserializeObject<JObject>(json);
var test = (JArray)obj["Test"];
var result = new {
A = (int)obj["A"],
B = (int)obj["B"],
Test = test.Cast<JArray>().Select(a => new Test {
Example = (int)a[0],
Example2 = (int)a[1],
Example3 = (int)a[2],
Example4 = (int)a[3],
Example5 = (int)a[4]
})
};
Related
I have a problem; I have various (too many) classes, that are linked as Parent/Child
I populate initially my top class while instantiate the others, as follows (works):
TopClass MyClass = new TopClass()
{
Headers = new someHeaders()
{
CorrID = "1234567890",
RequestID = "1234567890",
L_Token = "abcdefghijklmnopqrstuvwxyz"
},
Body = new someBody()
{
access = new AccessHeaders()
{
allPs = "allAcc",
availableAcc = "all"
},
CombinedServiceIndicator = false,
FrequencyPerDay = 10,
ValidUntil = "2020-12-31"
},
ResponseAttributes = new ConsentResponse()
{
myId = String.Empty,
myStatus = String.Empty,
myName = String.Empty,
_links_self_href = String.Empty,
status_href = String.Empty
}
};
The initials values that I populate above rarely change, but the Classes' properties change as the project goes on, and each class ends up having many properties.
I need to parse the properties and set values to any properties that match their name, but I can't seem to figure out why despite following official examples.
(I read the input data from a JSON string I use Newtonsoft - have tried everything out there)
I can't find a way to deserialize the JSON and assign any values to my properties without using the name of the property, i.e. without saying
MyClass.Body.access.allPs = "Hello"
but something like
var json = response.Content.ReadAsStringAsync().Result.ToString();
var a = new { serverTime = "", data = new object[] { } };
var c = new JsonSerializer();
or
if (myresponse.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
myresponse.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(myresponse, entry.Value);
//and how do I read the value, parse my TopClass and assign the value to correct property?
Could someone help me?
Values for the properties will get automatically assigned if the JSON is having the correct structure as per the class mentioned above.
Something like:
{
"Body":
"access:
{
"allPs" = "required value"
}
}
Then you can use:
var result = JsonConvert.DeserializeObject < TopClass > (json );
enter image description hereI have a keyValupair of Hotel details;:
//This is where the data comes from : -
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
dynamic hotels1 = (dynamic)json_serializer.DeserializeObject(jso);
var keyValuePairs = hotels1["hotels"];
var hotelList = keyValuePairs["hotels"]; // hotelList[0] ={'key'='Code' ;value='123'}
//{'key'='Name'
// ;value='Sheraton'}
how do i convert this to a list of Hotel
List<Hotel> hotaals = new List<Hotel>();
where Hotel is
public class Hotel
{
public int code { get; set; }
public string name { get; set; }
}
I use a for loop to map fields, but my great boss says its inefficient and i have to use Linq.
The loop i use
foreach (dynamic h in hotelList)
{
oneHotel = new Hotel();
oneHotel.code = h["code"];
oneHotel.name = h["name"];
myHotels.Add(oneHotel);
}
Well the brute force way would be to just project the dictionary to objects by hard-coding the properties:
List<Hotel> hotaals = hotelList.Select(kvp => new Hotel {
code = kvp['Code'],
name = kvp["Name"]
})
.ToList();
I would also challenge what your "great boss" means by inefficient".
So first you get your initial data:
var hotelList = keyValuePairs["hotels"];
Then use linq to create your new list:
var hotelObjects = hotelList.Select(hotel => new Hotel { code = hotel.key, name = hotel.name});
Now to be clear what linq is doing under the hood is an iterative loop through the objects (just like foreach) and creates a new Hotel object for each item in the hotelList and returns them as an IQueryable<Hotel>. Just apply .ToArray() or .ToList() if you don't want an IQueryable<>
Now from what it sounds like your initial List of hotel details isn't structured so you might have to modify my supplied linq query above to suit the structure of the list.
You may need something closer to this:
// Gives IQueryable<Hotel> as result
var hotelObjects = hotelList.Select(hotel => new Hotel{code = hotel["key"], name = hotel["name"]});
// Gives Array<Hotel> as result
var hotelObjects = hotelList.Select(hotel => new Hotel{code = hotel["key"], name = hotel["name"]}).ToArray();
// Gives List<Hotel> as result
var hotelObjects = hotelList.Select(hotel => new Hotel{code = hotel["key"], name = hotel["name"]}).ToList();
I am facing a problem I can not solve. and I hope someone can.
// I got Table saved in M.SQL server as in Picture
// Code
DB_Context MYDB = new DB_Context();
var ALL = MYDB.select(x => x );
I want to instantiate every string ( i.Position) as a new instant name of class ARTICLE.like the followings
foreach ( var i in ALL)
{
ARTICLE "i.Position" = new ARTICLE();
"i.Name".A_STOCK = i.Stock ;
}
// The Class
public Class ARTICLE
{
public int A_STOCK { get; set;}
}
// later I want to recall it to get its A_STOCK value , for example
int k1 = A1.A_STOCK ;
int k2 = A2.A_STOCK ;
//
In short , I want to retrieve all strings in Position Column and convert every string of them into a a new instant of class (ARTICLE) carries then instant name ...
Thank you very much ...
Pretty easy, just do it in your select using object initialization syntax.
DB_Context MYDB = new DB_Context();
var ALL = MYDB.select(x => { new ARTICLE { A_STOCK = x.Stock}; );
After making this change, ALL will contain a list of ARTICLE objects instead of a list of strings.
You can use a List<T>:
var articles = new List<ARTICLE>();
foreach(var i in ALL)
articles.Add(new ARTICLE() { A_STOCK = i.Stock });
var k1 = articles[0].A_STOCK;
var k2 = articles[1].A_STOCK;
///etc...
Btw, so many things wrong with your style.... Have a look at https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions
I have the code below which takes file containing XML and JSON and deserializes the JSON/XML into objects
using (var streamReader = new StreamReader("output.json"))
{
var rawJsonToLoad = streamReader.ReadLine();
var jsonWalkOrder = rawJsonToLoad.FromJson<MeterWalkOrder>();
Debug.WriteLine(jsonWalkOrder.Dump());
}
var xml = File.ReadAllText("WalkOrder.xml");
var xmlTest = xml.LoadFromXML<MeterWalkOrder>();
JSON
{
Name: Red Route,
Meters:
[
{
__type: "WindowsFormsApplication1.Classes.Meter, WindowsFormsApplication1",
MeterID: 1,
SerialNumber: 12345
},
{
__type: "WindowsFormsApplication1.Classes.Meter, WindowsFormsApplication1",
MeterID: 2,
SerialNumber: SE
}
]
}
[
1,
441,
2
]
XML
<MeterWalkOrder>
<Name>Red Route</Name>
<Meters>
<Meter>
<MeterID>1</MeterID>
<SerialNumber>12345</SerialNumber>
</Meter>
<Meter>
<MeterID>2</MeterID>
<SerialNumber>SE</SerialNumber>
</Meter>
</Meters>
</MeterWalkOrder>
Whilst on the surface this does work fine, there is a major drawback with it, it is using extension methods that are all extending the string data type
What I really want to be able to do is to say something like
var xml = File.ReadAllText("WalkOrder.xml");
var xmlTest = new MeterWalkOrder();
xmlTest.LoadFromXML(xml);
How can this be done with an extension method that extends an object rather than string?
I dont like the current approach because there is not enough flexibility in it, it forces the creation of new objects. For example, using the current method if I had a list of 5 meters and I wanted to add another 10 meters from a string of JSON I wouldnt be able to, because the fromJson would force me to recreate my meters list so I would only have the 10 meters in the file, not those 10 + the 5 that were already in the list
Paul
Edit - Following comments I have tried an extension method which actually demonstrates my issue perfectly
public static class ObjectExtensions
{
public static T PopulateFromJson<T>(this T obj)
{
using (var streamReader = new StreamReader("output.json"))
{
var rawJsonToLoad = streamReader.ReadLine();
obj = rawJsonToLoad.FromJson<T>();
}
return obj;
}
}
If I use the code below...
var testJson = new MeterWalkOrder();
testJson.Meters.Add(new Meter() { SerialNumber = "Meter 1" });
testJson.Meters.Add(new Meter() { SerialNumber = "Meter 2" });
testJson.PopulateFromJson();
...
After PopulateFromJson I want the object to be preserved - but because fromJson returns a new object it isnt - so my object would only contain the 2 meters from the JSON file, I actually want them added to the end of the list - in short I want to use the existing object not to have a new one created
Paul
So I have 2 json arrays as string in the below variables. They both have the header "invoices" and I would like to merge the two together so there is only 1 header and 4 items inside.
currently have:
var info1 = {"invoices":[{"url":"https://api.freeagent.com/v2/invoices/1","contact":"https://api.freeagent.com/v2/contacts/1"},{"url":"https://api.freeagent.com/v2/invoices/2","contact":"https://api.freeagent.com/v2/contacts/2"}]}
var info2 = {"invoices":[{"url":"https://api.freeagent.com/v2/invoices/3","contact":"https://api.freeagent.com/v2/contacts/3"},{"url":"https://api.freeagent.com/v2/invoices/4","contact":"https://api.freeagent.com/v2/contacts/4"}]}
Desired outcome:
var info3 = {"invoices":[{"url":"https://api.freeagent.com/v2/invoices/1","contact":"https://api.freeagent.com/v2/contacts/1"},{"url":"https://api.freeagent.com/v2/invoices/2","contact":"https://api.freeagent.com/v2/contacts/2"},{"url":"https://api.freeagent.com/v2/invoices/3","contact":"https://api.freeagent.com/v2/contacts/3"},{"url":"https://api.freeagent.com/v2/invoices/4","contact":"https://api.freeagent.com/v2/contacts/4"}]}
Is there any functions that I can use to do this?
The easiest way would be to deserialize them to 2 instances of the same class, add the array items together, and then serialize the object back to string.
Info info1 = // deserialize info1
Info info2 = // deserialize info2
info1.Invoices.AddRange(info2.Invoices);
string json = // serialize info1
Types:
class Info
{
List<Invoice> Invoices;
}
class Invoice
{
string URL;
string Contact;
}