I'm new to Json.net, so I'm not sure if I'm doing this the right / best way, but I can't figure this out:
I'm creating an output JObject:
JObject joOutput = new JObject();
Now, I have a list of paths to values:
a.b.c = 5
a.b.d = 7
a.c.q = 8
So I want to populate the joOutput object in the obvious way using that hierarchy.
I can't seem to find a way to set the value by path, obviously creating the path along the way if it doesn't exist.
I'm trying to split the path on the .'s and create the nodes, but I can't even get that far as the api is very confusing.
Can you point me in the right direction?
Thanks!
string a = #"{""b"": {""c"":5, ""d"":7}, ""c"": {""q"":8}}";
JObject joObject = JObject.Parse(a);
UPDATE:
var B = new JObject();
B.Add("c", 5);
B.Add("d", 7);
var C = new JObject();
C.Add("q", 8);
JObject A = new JObject();
A.Add("b", B);
A.Add("c", C);
UPDATE2, for completeness, here is Vladimir's method:
var B = new Dictionary<string, int> { ["c"] = 5, ["d"] = 7 };
var C = new Dictionary<string, int> { ["q"] = 5, ["8"] = 7 };
var A = new Dictionary<string, object> { ["b"] = B, ["c"] = C };
var AA = JObject.FromObject(A);
Try to solve your problem by using Dictionary with string key and object value.
Dictionary<string,object> myJsonObj = new Dictionary<string, object>;
Each element inside can be also same dictionary.
Related
I want to concat two array in LINQ dynamic parser.
I am sending dictionary input as below
object a= new object[]{1d,0d,1d};
object b = new object[]{};
var dict = new Dictionary<string, object>();
dict["KIStrike"] = a;
dict["NonKIStrike"] = b;
It throws {"')' or ',' expected"} exception, when I am executing below statement
var exp = "Enumerable.Concat(dict[\"KIStrike\"] as IEnumerable<object>, dict[\"NonKIStrike\"] as IEnumerable<object>)";
var param = Expression.Parameter(typeof(Dictionary<string, object>), "dict");
var lambda = DynamicExpressionParser.ParseLambda(new[] { param }, null, exp);
var result = lambda.Compile().DynamicInvoke(dict);
Whether my expression is incorrect. Please let me know if you have any solution. Thanks in advance!!!.
Currently having an issue creating a reusable object that I will need to use in a JSON construct string function.
Currently I have the following to create the bulk of the JSON string:
var data = new
{
record = new
{
value1 = Row.value1,
value2 = Row.value2,
form_values = new Dictionary<string, string>()
}
};
data.record.form_values["833b"] = Row.value3.ToString();
data.record.form_values["98wq"] = BuildMultiSelectList(Row.value3.ToString());
public object BuildMultiSelectList(string datavalue)
{
var choicelist = new {
choice_values: [datavalue],
other_values: [],
};
return choicelist;
}
The top half all works fine, though the function BuildMultiSelectList is giving errors such as "choice_values" does not exist in the current context and datavalue does not exist in the current context.
Any insight on why this has gone a bit rouge will be appreciated.
May be you are just mixing colon : with =?
var choicelist = new {
choice_values = new string[] {datavalue},
other_values = new[] {},
};
I'm trying to convert some R code script into C# code via RDotNet Library.
I was able to convert a big part but there's an issue while creating data.table in C#.
Above is my code example:
Dictionary<string, List<string>> myDic = new Dictionary<string, List<string>>();
// populate the dictionary
var colNames = new List<string>() { "col1", "col2"};
IEnumerable[] columns = new IEnumerable[2];
columns[0] = myDic.Keys;
columns[1] = myDic.Values;
var mydata = engine.CreateDataFrame(columns.ToArray(), colNames.ToArray(), stringsAsFactors: false);
when i use the variable mydata, I got an exception
Cannot convert type System.Collections.Generic.List`1[System.String][] to an R vector
Are you sure you want to create a dataframe column that contains a list of strings in each cell? It's not how you create a dataframe in R. The code below works when you replace Dictionary<string,List<string>> with Dictionary<string,string>.
Dictionary<string, string> myDic = new Dictionary<string, string>() {
{ "a","aaaa"},
{ "b","bbbb"},
{ "c","cccc"}
};
// populate the dictionary
var colNames = new List<string>() { "col1", "col2" };
IEnumerable[] columns = new IEnumerable[2];
columns[0] = myDic.Keys.ToArray();
columns[1] = myDic.Values.ToArray();
REngine engine = REngine.GetInstance();
var mydata = engine.CreateDataFrame(columns, colNames.ToArray(), stringsAsFactors: false);
please tell me, how do I get the json like this:
dynamic packet = new ExpandoObject();
packet.type = "somethink";
packet.user = 12345;
packet.nets[0].amout = 123;
packet.nets[0].lower = 0;
packet.nets[1].amout = 345;
packet.nets[1].lower = 1;
string input = Newtonsoft.Json.JsonConvert.SerializeObject(packet);
Its not workig, error:
An unhandled exception of type "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" in System.Core.dll
For more information: "System.Dynamic.ExpandoObject" does not contain definitions of "nets"
Thanks.
It's the ExpandoObject who's a dynamic object. The rest of properties should be other ExpandoObject instances or regular objects, arrays, collections...
For example:
packet.nets = new[]
{
new { amount = 123, lower = 0 },
new { amount = 345, lower = 1 }
}
Or:
packet.nets = new[]
{
new Dictionary<string, int> { { "amount", 345 }, { "lower", 0 } },
new Dictionary<string, int> { { "amount", 123 }, { "lower", 1 } }
}
There're many other approaches, including the use of instances of concrete classes.
Firstly, you need create nets in packet object, like this:
packet.nets = new dynamic[2];
And initialize the objects in nets, if you want with `ExpandoObject too:
packet.nets[0] = new ExpandoObject();
packet.nets[1] = new ExpandoObject();
Then is done, complete code:
dynamic packet = new ExpandoObject();
packet.type = "somethink";
packet.user = 12345;
packet.nets = new dynamic[2];
packet.nets[0] = new ExpandoObject();
packet.nets[0].amout = 123;
packet.nets[0].lower = 0;
packet.nets[1] = new ExpandoObject();
packet.nets[1].amout = 345;
packet.nets[1].lower = 1;
string input = Newtonsoft.Json.JsonConvert.SerializeObject(packet);
You first need to declare nets. For example
packet.nets = new Dictionary<int, dynamic>();
Then you'll need to instantiate the instances of nets
packet.nets[0] = new {amount = 123, lower = 0};
The result being
dynamic packet = new ExpandoObject();
packet.type = "somethink";
packet.user = 12345;
packet.nets = new Dictionary<int, dynamic>();
packet.nets[0] = new { amount = 123, lower = 0 };
packet.nets[1] = new { amount = 345, lower = 1 };
Sounds a little complex but here is what I am trying to do:
I am filtering certain properties of MyObject in List<MyObject> into a new LINQ object as:
var filteredMyObjects = from r in myObjects select new { r.ComponentName, r.Group, r.Key };
The problem is now that Properties ComponentName, Group and Key should come as an input (for example List<string> of property names). This is used in my logic for exporting data into excel.
I have been trying to combine it with this idea:
typeof(MyObject).GetProperty(property).GetValue(objectInstance) as string
But cannot wrap my head around how to implement it.
EDIT:
See example of what I need to achieve:
List<string> userDefinedPropeties = new List<string> {Property1, Property2, Property3 ... }
var filteredMyObjects = from r in myObjects select new { r.Property1, r.Property2, r.Property3 ... };
Ideal answer would look like this, except this solution does not work
in my case:
Linq access property by variable
You can't use an anonymous object for this, your best bet is to use an expando object
//List<string> userDefinedPropeties is a parameter
List<dynamic> filteredMyObjects = new List<dynamic>();
foreach (var i in filteredMyObjects)
{
dynamic adding = new ExpandoObject();
foreach (var prop in userDefinedPropeties)
{
adding[prop] = i.GetType().GetProperty(prop).GetValue(i);
}
filteredMyObjects.Add(adding);
}
// all of the elements of the filtered list can be accessed by using
// item.`PropertyName`
Also a better way to phrase your question would be to say that you want to pass an object that only contains the properties that the user requested, not sure why the UI wouldn't be able to handle more properties than requested, but you have explained you don't have control over the design
You could fake dynamic properties using Dictionary:
public class CustomObject
{
Dictionary<string, object> _properties = new Dictionary<string, object>();
public CustomObject(dynamic parentObject, List<string> properties)
{
foreach (string propertyName in properties)
_properties[propertyName] = parentObject.GetType().GetProperty(propertyName).GetValue(parentObject, null);
}
public object this[string name]
{
get
{
if (_properties.ContainsKey(name))
{
return _properties[name];
}
return null;
}
set
{
_properties[name] = value;
}
}
}
Use example:
var myObjects = new List<MyObject>()
{
new MyObject(1, "Component1", 1, 1),
new MyObject(2, "Component2", 2, 2),
new MyObject(3, "Component3", 3, 3),
new MyObject(4, "Component4", 4, 4),
new MyObject(5, "Component5", 5, 5),
new MyObject(6, "Component6", 6, 6),
new MyObject(7, "Component7", 7, 7),
new MyObject(8, "Component8", 8, 8),
};
var properties = new List<string>()
{
"ComponentName", "Group", "Key"
};
List<CustomObject> myCustomObjects = new List<CustomObject>();
foreach (MyObject myObject in myObjects)
myCustomObjects.Add(new CustomObject(myObject, properties));