I've tried some examples on here but am tearing my hair out.
I do a query and it returns JSON, inside the JSON are lots of hashes, eg.
{ "gjwiegjeigj": { ....}, "gjeeigjwoeigj": {...} ... }
I want to loop through each of these, and deserialize the contents into an object.
I've created the object, myObject which has all the fields, but I am stuck on deserialising.
I can deserialise straight from the base object using JsonConvert.DeserializeObject but I can't do that, I need to loop through and do that to the children.
I want an array of my custom objects with all the fields taken from the Json as a result of this, I don't care about the title of each one (the garbage hash).
Any ideas? I know I can loop through, which gives me lots of JTokens but that's where I get stuck.
Edit: Reading your question again, you mention both knowing and not knowing all the fields. It sounds like you really don't know exactly what fields the JSON string will contain.
For cases like this, I suggest you use dynamic -- this is where it shines. If you do know all the field names, your class should be deserializing without any issue.
What have you tried? Show us some real code, and real exceptions or problems.
To deserialize into a list of dynamic objects is simple:
dynamic toReturn = JsonConvert.DeserializeObject<List<dynamic>>(rawJson);
You should get back a list of dynamic objects. You can poke it for the fields you want:
Console.WriteLine(toReturn.First().gjwiegjeigj);
So I figured it out, basically to get from a collection JTokens which is what I get when I iterate through .Children() on my JSON object, I can either cast it to a JProperty and do .Name to get the name or .Value to get the value, or I can deserialize directly into an object, essentially like this:
MyObject record = (MyObject)JsonConvert.DeserializeObject(myRow.Children().First().ToString(), typeof(MyObject), settings);
Then I don't know need to know the name of the property I am deserializing.
Related
I have asked questions regarding serialization and deserialization before regarding ServiceStack OrmLite, and I am not sure if this is the same issues I've had before, but I don't think so.
Basically, I have a public Dictionary<string, object> _CustomProperties where I store some random data.
I add random data to this dictionary like this:
ms._SetCustomProperty<bool>("ConvertedContactItems", true);
like so:
and this is blobbed using OrmLite, like this:
When I read it back (using Untyped API), I do as below:
bool hasConvertedContactItems = actor._GetCustomProperty<bool>("ConvertedContactItems");
but the boolean true is now a string, not a bool:
The question is: what am I doing wrong? I have a slight feeling this might be an answer that sounds the same as before, but I am not quite sure about it.
UPDATE 1
Below is a Dictionary<string, object> serialized using JsvSerializer in OrmLite. I thought that since it cannot properly deserialze a boolean, it for sure cannot deserialize a custom object. Well, it seems that custom objects have sometimes the type info in there. The CustomerSettings gets correctly deserialized, but bool, datetime etc, does not.
So, if type info is added for custom objects, why not for primitives so we can deserialize them correctly? (Too bloated? Then why for custom objects?)
{
MyBoolProp:True, // <-- why not emit type info, like CustomerSettings below?
MyDateTime:2018-08-01T22:49:58.7586897+02:00, // <-- why not emit type info
Settings:
{
__type:"Commons.CustomerSettings,Commons",
NotifStarted:False,
NotifFinished:True
}
}
The serialized output does not contain any Type information so if you try to deserialize it into an object it doesn't know what Type to deserialize into so it leaves it as a string which is also an object.
I'd recommend avoid using object and instead if you want to serialize untyped key/value pairs to instead serialize a Dictionary<string,string> that way the value is always stored and retrieved as a string.
Of course if you need to serialize a typed Dictionary like Dictionary<string,bool> then you should use that instead.
I'm receiving some oddly formatted JSON that I want to store in a single object. It looks something like this:
{
"parentObject":
{
"id": 123456,
"pointlessChildObject":
{
"stringThatCouldBeStoredInParent": "test",
"epochTimeThatCouldBeStoredInParent": "1520452800"
}
}
}
At first, I thought this would be simple thanks to a solution by Brian Rogers that I found: Can I specify a path in an attribute to map a property in my class to a child property in my JSON?
However, if you implement this solution, you can't use another converter for converting those values into something else at the same time (A nested [JsonConverter(typeof(SecondsEpochConverter))] for the epoch time for example). And of course, because this is C#, you can't have a set that's different than your type (convert int to DateTime in set). I'm trying to add code to Brian's solution such that it calls the nested converter, but now we're getting into ridiculous territory; I'm creating a single use JSONTextReader just to have the value passed to the nested converters, and I'm pretty sure I'm overthinking this.
Does anyone know of a better solution?
I have a predefined data format, which requires me to have an object like this:
settings:{
settingA:'someValueFromSql',
settingB:'someValueFromAD'
settingC:'someValueFromConfigFile',
settingD:'someValueFromReflection',
settingE:42,
...
}
This settings object is in fact a huge mess of data stitched together from many different sources, but this is how the data is expected by the frontend. I'd like to put the "get/process all data from one source" in a function each, and tape the object together in the end.
So I would have one object
sqlSettings:{
settingA:'someValueFromSql',
settingG:'someOtherValueFromSql',
...
}
returned by function a, and an object
adSettings:{
settingB:'someValueFromAD',
settingV:'someOtherValueFromAD',
...
}
returned by function b, and an object
settings includes adSettings, sqlSettings
where, with at most two simple steps, I can "join together" both objects into a flat third object.
Is this possible with fixed-size objects, without using a generic Dictionary, or am I barking up the wrong tree?
(I'm sure this question was already asked on SO, but I guess I don't find the right words)
It's not possible with a "normal" object, but you can do it with an ExpandoObject and the dynamic keyword. But you need at least .net 4.0
dynamic settings = new ExpandoObject();
//If you try to assign a property that doesn't exist, it is added to the object.
settings.SettingA="sfgd"
Anyway I discourage using this approach. why you don't want to use a IDictionary<string, object> or better a IDictionary<string, MyCustomSettingObject>
--------------------UPDATE---------------------
if the only thing that stops you from using a dictionary is the serialization you can implement the IXmlSerializable Interface and ouput the xml you like:
Proper way to implement IXmlSerializable?
If those partial setting objects have fixed size (meaning fixed number of properties), then you can definitely create a flat object with e.g. only properties to fit all the values in. Then to ease your work, you can try to use Automapper to map the partial objects to the "grouped" object.
http://automapper.codeplex.com/
Otherwise, you will have to stick with the dictionary.
The serialization of the array returns the following JSON:
[{"Code":"AAAA","Description":"Description of AAAA"},{"Code":"BBBB","Description":"Description of BBBB"}]
My goal is to return the following JSON:
{"AAAA":{"Description":"Description of AAAA"},"BBBB":{"Description":"Description of BBBB"}}
You can achieve something simliar (not exactly the same you are expecting) if instead of serializing an array, build a temporary Dictionary and serialize it.
var dict = new Dictionary<String, YourClass>();
foreach (YourClass yourObj in listOfObjs)
{
dict[yourObj.Code] = yourObj;
}
// then serialize "dict"
You could add a rule to your JSON serializer to make it avoid serializing "code" property in YourClass, and you will end up with a JSON object exactly as you show in your example.
You'll need to either use a class that has the "AAAA" and "BBBB" properties, or you'll need to serialize a dictionary instead. As it is, you're serializing an array and getting an array.
The table on this blog post shows several search starting points.
.Net has built-in System.Web.Script.Serialization.JavaScriptSerializer, here, with examples
The .Net one doesn't specially serialize Dictionary the way you want, but some of the others do, I believe. However, I think there are reasons NOT to want a general serialization routine the way you've requested - though I can't list them certainly.
I'm writing a custom deserializer that will deserialize a list by deserializing each of the individual objects in the collection and then putting it together.
Basically my code looks like this:
//myField is a FieldInfo that represents the field we want to put the data in
//resultObject is the object we want the data to go into
List<Object> new_objects = new List<Object>();
foreach (String file_name in file_name_list)
{
Object field_object = MyDeserialization(file_name)
new_objects.Add(field_object)
}
myField.SetValue(resultObject, new_objects);
But this gives an error on the SetValue because (for example) I am trying to put a List(Object) into a List(Int32). Note that this problem only occurs with collections. The following code:
Object new_object = MyDeserialization(file_name)
myField.SetValue(resultObject, new_object)
works just fine provided that the runtime type of the result of MyDeserialization(file_name) is actually compatible with the type of myField. What is the problem here, and is there a way to make the collection deserialization work? (I've tried replacing the List(Object) declaration with myField.FieldType and that won't even compile.
Collections do not offer covariance... a List<int> simply isn't a List<object> (or v.v.). As such, you need to identify the T, for example like so (using the FieldInfo.FieldType) - and create the right type of list in the first place.
For convenience, once created it may be simpler to use the non-generic IList interface:
Type listType = typeof(List<>).MakeGenericType(itemType);
IList list = (IList)Activator.CreateInstance(listType);
list.Add(...); // etc
However; I must stress - writing a full (and robust) serializer is a lot of work. Do you have a specific reason? Many of the inbuilt serializers are pretty good - for example DataContractSerializer - or 3rd party, such as Json.Net, and (if I do say so myself) protobuf-net.
The problem is that .NET can't know that your List is actually a List. The following code should work:
//myField is a FieldInfo that represents the field we want to put the data in
//resultObject is the object we want the data to go into
List<MyType> new_objects = new List<MyType>();
foreach (String file_name in file_name_list)
{
Object field_object = MyDeserialization(file_name)
new_objects.Add((MyType)field_object)
}
myField.SetValue(resultObject, new_objects);
For Fun Linq Extra Credit (assuming file_name_list is IEnumerable):
myField.SetValue(resultObject, file_name_list
.Select(s => MyDeserialization(s))
.Cast<MyType>()
.ToList());