In c# language using dictionary to store and that dictionary converted to object at finally that object stored to SQL server..
You could serialize it and save it as a json string. You could use http://nuget.org/packages/newtonsoft.json to serialize and deserialize you dictionary.
If you really want to convert the dictionary to an object that has the items of the dictionary as properties, you can use ExpandoObject:
var dict = new Dictionary<string, object> { { "Property", "foo" } };
var eo = new ExpandoObject();
var eoColl = (ICollection<KeyValuePair<string, object>>)eo;
foreach (var kvp in dict)
{
eoColl.Add(kvp);
}
dynamic eoDynamic = eo;
string value = eoDynamic.Property;
But I'm not sure how is doing that going to help you
Related
I have a dictionary which is dynamically generated. In the dictionary, for a single Key, there are multiple values. I am trying to access one of the values in those multiple values. My code so far:
var result = new Dictionary<string, object>();
var dictionary = deserialisedResult as IDictionary<string, object>;
foreach (var item in dictionary)
{
result.Add(item.Key, item.Value);
}
object o = result;
string[] names = o.GetType().GetProperties().Select(p => p.Name).ToArray();
foreach (var prop in names)
{
object propValue = o.GetType().GetProperty(prop).GetValue(o, null);
var value = propValue.GetValue(o,null);
}
But this is not working.
I need to get the values for 'resource'.
When I add watch, I see it nested as such:
Following line is causing issue out here:
string[] names = o.GetType().GetProperties().Select(p => p.Name).ToArray();
GetType() for Object base class type will not yield a Type, which can provide the PropertyInfo[], that you are looking for, even otherwise you are trying to run it for Dictionary<string,object> type, which anyway doesn't have properties to help find the relevant information. For it the Type would always be Dictionary
What you need is fetch the key collection from Dictionary and use them to fetch the values stored in the Dictionary
foreach (var key in result.Keys)
{
var value = result[key];
}
Solution is based on code provided in the question, I am not sure if you have further requirements
Originally I deserialize a JSON string into a dynamic type List, this worked fine until moving it to the server at which point the dynamic list stopped working. The only answer I could find is that this is not abnormal behavior for lists. The original question
So from that I changed my dynamic list to an ExpandoObject
dynamic root = JsonConvert.DeserializeObject<ExpandoObject>(jsonstring, new ExpandoObjectConverter());
Originally in my dynamic list I called
root.record.form_values.Remove("f161");
root.record.form_values.Remove("41df");
root.record.form_values.Remove("a228");
root.record.Remove("changeset_id");
Which worked as expected removing those objects from the List which I eventually turn back into JSON and send it back to an API.
After doing some reading on ExpandoObjects I found that to delete you need to throw it out to a IDictionary in order to have the .Remove functionality.
So I did this:
dynamic dict = (IDictionary<string, object>)root;
And then replaced my code with:
dict.record.form_values.Remove("f161");
dict.record.form_values.Remove("41df");
dict.record.form_values.Remove("a228");
dict.record.Remove("changeset_id");
This resulted in the error
'System.Dynamic.ExpandoObject' does not contain a definition for
'Remove'
So after a bit more reading I tried the following:
dict = (IDictionary<string, object>)root.record.form_values.Remove("f161");
dict = (IDictionary<string, object>)root.record.form_values.Remove("41df");
dict = (IDictionary<string, object>)root.record.form_values.Remove("a228");
dict = (IDictionary<string, object>)root.record.Remove("changeset_id");
Which resulted in the same error...
If anyone can give me a clue on where to go to from now, that would be great.
FYI The JSON Structure looks as such:
"{
\"record\":{
\"status\":\"somevalue\",
\"form_values\":
{
\"833b\":\"somevalue\",
\"683b\":\"somevalue\",
\"c9ca\":{\"other_values\":[],\"choice_values\":[\"somevalue\"]}
},
\"latitude\":somevalue,
\"longitude\":somevalue
}
}"
The original code with the DynamicList (Which worked) looks as such:
string jsonstring = data;
var root = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonstring);
root.record.assigned_to = assignedto;
root.record.assigned_to_id = assignedtoid;
root.record.status = status.ToString();
root.record.bb42 = abudgetunit;
root.record.f694 = abudgetunitstr;
root.record.form_values.Remove("f161");
root.record.form_values.Remove("41df");
root.record.form_values.Remove("a228");
root.record.Remove("changeset_id");
You're very close. There are nested expando objects in the structure, and you've only converted the first one. If you find the nested objects and convert all the way down to the form_values then it will work.
dynamic root = JsonConvert.DeserializeObject<ExpandoObject>(jsonstring, new ExpandoObjectConverter());
var rootDict =(IDictionary<string, object>) root;
var recordDict = (IDictionary<string, object>) rootDict["record"];
var formValuesDict = (IDictionary<string, object>) recordDict ["form_values"];
formValuesDict.Remove("683b");
I have a json object which is been converted to list of Dictionary. The json is as follows:
{
"DataList":
{"Non Fuel":
{
"sn":"/DataXmlProduct/Customers/DataXml/Customer/DueDate",
"ItemCode":"/DataXmlProduct/Customers/DataXml/Customer/InvoiceNo",
"Qty":"/DataXmlProduct/Customers/DataXml/Customer/CustomerNo",
"Amount":"DataXml/Customer/TotalCurrentCharges"
},
"Fuel":{
"sn":"/DataXmlProduct/Customers/DataXml/Customer/InvoiceNo",
"ItemCode":"/DataXmlProduct/Customers/DataXml/Customer/InvoiceNo",
"Amount":"DataXml/Customer/TotalCurrentCharges"
}
}
}
The result is (Dictionary<string, object>), Here the value of each dictionary is again a dictionary and I need to dynamically iterate through each values of the dictionary and get the last key & value where the value is a Xpath and need to get the values from the xpath.
Kindly help me with a solution to iterate through the dictionary. It should be generic since the json format can vary based on user input.
Assuming that the actual values (such as the contents of fuel) come out as a KeyValuePair<string, object>, then you could do this with a recursive method:
public static void ParseData(object source)
{
Dictionary<string, object> Dict;
KeyValuePair<string, object> Kvp;
if ((Dict = source as Dictionary<string,object>) != null)
{
foreach(var kvp in Dict)
{
Console.WriteLine(kvp.Key);
ParseData(kvp.Value);
}
}
elseif ((Kvp = source as KeyValuePair<string, object>) != null)
{
Console.WriteLine("{0}{1}", Kvp.Key, Kvp.Value);
}
}
This makes an assumption or two, but that will iterate through all the data assuming its made of dictionaries and kvps.
Edit: If you've got an XPath and want to get a node then what you'll need to do is prepare an XMLDocument with the data in. You can use the code above to walk through the data to help you build an XMLDocument and then query the document with your XPath.
Here's the basic code for processing all the data:
static void IterateDictionary(Dictionary<string, object> dictionary)
{
foreach (var pair in dictionary)
{
System.Console.WriteLine("Processing key: " + pair.Key);
object value = pair.Value;
var subDictionary = value as Dictionary<string, object>;
if (subDictionary != null)
{
// recursive call to process embedded dictionary
// warning: stackoverflowexception might occur for insanely embedded data: dictionary in dictionary in dictionary in . etc
IterateDictionary(subDictionary);
}
else
{
// process data
System.Console.WriteLine("data: {0}", value);
}
}
}
hope this helps
i'll suggest using Json.NET to serialize your objects, however, you've mentioned that the input is dynamic, but are the attributes standardized? Looking at your sample, there are several repeated fields. You can deserialize the json into your classes by doing
JsonConvert.DeserializeObject<YOUR_CUSTOM_OBJECT>
I'm developing an application that reads some JSON data and makes some statistics, but now I've run into a problem.
I have a string like this:
{
"position":[
{
"someKey1":"someVal1",
"someKey2":"someVal2",
},
{
"someKey1":"someVal3",
"someKey2":"someVal4",
}
}
I want to access the someKeys and someValues.
I'm converting it to a dictionary like this:
Dictionary<string, object> values = deserializeJSON(json_string);
Edit 1: Sorry, forgot to add deserializeJSON:
private Dictionary<string, object> deserializeJSON(string p_jsonObject)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Deserialize<Dictionary<string, dynamic>>(p_jsonObject);
}
Now I have trouble getting access to the list of values with the key "position". If I try to print the type of values["position"] I get:
System.Collections.ArrayList
So I thought I could just iterate through this, but I can't. I tried using enumerator (read in here that it would make it possible to iterate over the objects, and that I have to add it to an ArrayList to cast it):
ArrayList arr = new ArrayList();
IEnumerable enumerable = values["position"] as IEnumerable;
foreach (object element in enumerable)
{
arr.Add(element);
}
When I print arr[0] I get:
System.Collections.Generic.Dictionary`2[System.String,System.Object]
Here I'm confused. I assume it's the list of someKeys and someVals, which should be correct, right?
Now I've tried, with no luck, getting access to these values. I tried arr[0]["someKey1"] but get an error that I cannot apply indexing to 'object'.
Any ideas on a solution? Ideally a more elegant solution? :)
Thanks in advance
You can use Linq to JSON (add Newtonsoft's JSON.NET from NuGet):
JObject jo = JObject.Parse(json);
var value = (string)jo["position"][1]["someKey1"]; // someVal3
Another sample:
JObject jo = JObject.Parse(json);
JArray positions = (JArray)jo["position"];
foreach (var item in positions)
{
// use (string)item["someKey1"]
// use (string)item["someKey2"]
}
You can access the elements as follows:
var enumerable = (IEnumerable)values["position"]; // Will get you the enumerable ArrayList
(Dictionary<string,object>)values["position"][0]; // Will get you the First element of the ArrayList
(string)values["position"][0]["someKey1"]; // Will get you someKey1 from the first position of position
I have an IEnumerable<KeyValuePair<string,string>>, from which I would like, ideally, an anonymous object which has the keys as property names and the values as property values.
I've tried various selection expressions (none of which even compiled...) and an approach using ExpandoObject (see below), but without success. Is there a good way to do this? If possible, I'd like to avoid an extra explicit iteration over the collection (i.e. do it all with a LINQ statement of some sort).
This is what I've tried so far. I hope it also clarifies what I'm trying to do:
var kvps = getProps(); // returns IEnumerable<KeyValuePair<string,string>>
dynamic o = new ExpandoObject();
foreach (var kvp in kvps)
{
o.Add(kvp);
}
This is OK at compile time, but at runtime I get a YSOD stating 'System.Dynamic.ExpandoObject' does not contain a definition for 'Add' - I guess it works at compile time because o is dynamic, so the compiler can't know if a method .Add() has been added to it since it was instantiated. The odd thing is, that on the MSDN documenation page for ExpandoObject .Add() is listed as one of several "explicitly implemented interface methods".
It is not necessary for me to get this into a dynamic object - I just need to get something that has property names and values according to the keys and values of the key-value pairs.
Update: Well, this is embarrassing. Turns out this was something of an XY-problem too.
I'm trying to render this to JSON using the built-in features of ASP.NET MVC, by simply returning Json(data) in my controller. The answers all worked very well to do what I first asked, but when I pass this object as data I still don't get what I want:
// What I get:
[
{ Key: 'firstkey', Value: 'FirstValue' },
{ Key: 'secondKey', Value: 'secondValue' }
]
// What I want:
{ firstKey: 'FirstValue', secondKey: 'secondValue' }
Apparently, an ExpandoObject with the relevant properties added didn't cut it - it was cast to a dictionary before rendering...
You need to use the ExpandoObject as an IDictionary<string, object> while populating it:
var kvps = getProps(); // returns IEnumerable<KeyValuePair<string,string>>
IDictionary<string, object> o = new ExpandoObject();
foreach (var kvp in kvps)
{
// Or use Add(kvp.Key, kvp.Value), if you want
o[kvp.Key] = kvp.Value;
}
dynamic d = o;
// Now you can use the properties
ExpandoObject explicitly implements IDictionary<string, object> - so you need to cast it to one first:
var kvps = getProps();
dynamic o = new ExpandoObject();
var dict = o as IDictionary<string, object>;
foreach (var kvp in kvps)
{
dict.Add(kvp.Key, kvp.Value);
}
Now you can use o as you would expect:
var example = o.YourKey;
I'm trying to render this to JSON using the built-in features of ASP.NET MVC, by simply returning Json(data) in my controller.
Interesting.
To do that, you serialize a dictionary, not an ExpandoObject. MVC 3's JSON serializer already does that with a dictionary. All you have to do is convert your IEnumerable<KeyValuePair<string, object>> to a dictionary:
var kvps = getProps();
var dictionary = kvps.ToDictionary(k => k.Key, v => v.Value);
return Json(dictionary, JsonRequestBehavior.AllowGet); //take out allow get if you don't need it.
No dynamics required.
I think you have to cast your expando object to IDictionary and call Add(string, object)