field 'params' with an expando object in C# - c#

I have the following in C#:
dynamic JsonObject = new ExpandoObject();
JsonObject.action = Action;
JsonObject.arguments = JsonArguments;
JsonObject.id = Id;
JsonObject.sig = Signature;
var Json = JsonConvert.SerializeObject(JsonObject);
and I need to change:
JsonObject.arguments = JsonArguments;
into:
JsonObject.params = JsonArguments;
but I can't use params as a field name with an expando object.
What would be a good workaround to build that json?
It's to use with deribit.com. They've released API V2 and changed some of the names, but I guess didn't think about that case.

You could convert the expando into a dictionary or use a dictionary directly, for sample:
var jsonObject = new ExpandoObject() as IDictionary<string, Object>;
jsonObject.Add("action", Action);
jsonObject.Add("params", JsonArguments);
jsonObject.Add("id", Id);
jsonObject.Add("sig", Signature);
var json = JsonConvert.SerializeObject(JsonObject);

Related

Dynamically creating an object with dynamic children using data at runtime with ExpandoObject in C#

I've created a dynamic object and set properties and values to it at runtime using ExpandoObject
dynamic parentDynamic = new ExpandoObject();
var parentName = "GroupOne";
((IDictionary<String, Object>)parentDynamic)[parentName] = "default";
Console.WriteLine(parentDynamic.GroupOne);
The Console successfully outputs "default" as expected.
I've also created a child object with multiple properties in the same manner
dynamic childDynamic = new ExpandoObject();
var childProperty1 = "FirstName";
var childProperty2 = "LastName";
var childProperty3 = "Occupation";
((IDictionary<String, Object>)childDynamic)[childProperty1] = "John";
((IDictionary<String, Object>)childDynamic)[childProperty2] = "Smith";
((IDictionary<String, Object>)childDynamic)[childProperty3] = "Plumber";
Console.WriteLine(childDynamic.Occupation);
The Console successfully outputs "Plumber" as expected.
Where I am getting in a jam is when I attempt to add the childDynamic object to the parentDynamic object and give it a name at runtime. Here is my latest failed attempt:
var childName = "ChildOne";
((IDictionary<String, Object>)((IDictionary<String, Object>)parentDynamic)[parentName])[childName] = childDynamic;
Console.Write(parentDynamic.GroupOne.ChildOne.Occupation);
The error I am getting when attempting the assignment is: Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.
Essentially I would like to be able access parentDynamic.GroupOne.ChildOne.Occupation and get back "Plumber" or parentDynamic.GroupOne.ChildOne.FirstName and get back "John"
Originally I was trying to make my assignments all at once like so
parentDynamic["GroupOne"]["ChildOne"]["Occupation"] = "Plumber"
But I get the error Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject' Which is why I went down the path of creating a parent and child object and casting them as Dictionary objects first. Ideally I would like to just do something like the above as it's MUCH simpler.
In order to be able to use parentDynamic.GroupOne.ChildOne syntax, GroupOne property should also be dynamic ExpandoObject while in your case it is a string.
Something like this:
dynamic parentDynamic = new ExpandoObject();
parentDynamic.GroupOne = new ExpandoObject();
parentDynamic.GroupOne.ChildOne = new ExpandoObject();
parentDynamic.GroupOne.ChildOne.FirstName = "John";
parentDynamic.GroupOne.ChildOne.LastName = "Smith";
parentDynamic.GroupOne.ChildOne.Occupation = "Plumber";
or with IDictionary<string, object> casts:
IDictionary<string, object> parent = new ExpandoObject();
IDictionary<string, object> group = new ExpandoObject();
IDictionary<string, object> child = new ExpandoObject();
child["FirstName"] = "John";
child["LastName"] = "Smith";
child["Occupation"] = "Plumber";
parent["GroupOne"] = group;
group["ChildOne"] = child;
dynamic parentDynamic = parent;
Console.WriteLine(parentDynamic.GroupOne.ChildOne.Occupation);

Getting a specific field from a JSON string without deserializing in C#

I currently have a REST app which returns a JSON string something like:
[{error: "Account with that email exists"}]
For when an error is thrown. I don't want to deserialize it into a custom "error" object, because it seems a bit wasteful and pointless. Is there a simple way to just extract a specific field out of a JSON string without making a custom class to reflect it.
Thanks
You have a couple of options if you don't want to create a custom class, you can deserialize to dynamic:
dynamic tmp = JsonConvert.DeserializeObject(yourString);
string error = (string)tmp.error;
Or deserialize to a dictionary:
var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>();
string error = dic["error"];
No need third party libraries. Use native JavaScriptSerializer.
string input = "[{error: \"Account with that email exists\"}]";
var jss = new JavaScriptSerializer();
var array = jss.Deserialize<object[]>(input);
var dict = array[0] as Dictionary<string, object>;
Console.WriteLine(dict["error"]);
// More short with dynamic
dynamic d = jss.DeserializeObject(input);
Console.WriteLine(d[0]["error"]);
Have a look at JObject.
dynamic obj = JObject.Parse("{ myerrors: [{error: \"Account with that email exists\"}] }");
var a = obj.myerrors[0];
string error = a.error;

Converting dynamic type to dictionary C#

I have a dynamic object that looks like this,
{
"2" : "foo",
"5" : "bar",
"8" : "foobar"
}
How can I convert this to a dictionary?
You can fill the dictionary using reflection:
public Dictionary<String, Object> Dyn2Dict(dynamic dynObj)
{
var dictionary = new Dictionary<string, object>();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dynObj))
{
object obj = propertyDescriptor.GetValue(dynObj);
dictionary.Add(propertyDescriptor.Name, obj);
}
return dictionary;
}
You can use a RouteValueDictionary to convert a C# object to a dictionary. See: RouteValueDictionary Class - MSDN. It converts object properties to key-value pairs.
Use it like this:
var toBeConverted = new {
foo = 2,
bar = 5,
foobar = 8
};
var result = new RouteValueDictionary(toBeConverted);
If the dynamic value in question was created via deserialization from Json.Net as you mentioned in your comments, then it should be a JObject. It turns out that JObject already implements IDictionary<string, JToken>, so you can use it as a dictionary without any conversion, as shown below:
string json =
#"{ ""blah"" : { ""2"" : ""foo"", ""5"" : ""bar"", ""8"" : ""foobar"" } }";
var dict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
dynamic dyn = dict["blah"];
Console.WriteLine(dyn.GetType().FullName); // Newtonsoft.Json.Linq.JObject
Console.WriteLine(dyn["2"].ToString()); // foo
If you would rather have a Dictionary<string, string> instead, you can convert it like this:
Dictionary<string, string> newDict =
((IEnumerable<KeyValuePair<string, JToken>>)dyn)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());
You can use Json.Net to deserialize it to dictionary.
string json = dynamicObject.ToString(); // suppose `dynamicObject` is your input
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Very similar to ema answer, but with a one-liner using LINQ magic:
Dictionary<string, object> myDict = sourceObject.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(sourceObject, null));
Another way is using System.Web.Helpers.Json included in .NET 4.5.
Json.Encode(object) and Json.Decode. Like:
Json.Decode<Generic.Dictionary<string, string>>(value);
MSDN: https://msdn.microsoft.com/en-us/library/gg547931(v=vs.111).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
Regards,
MarianoC.
You can do it with jsonSerializer. And it requires System.Net.Extensions reference. Here is a sample code.
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string,string>>(jsonText);
var place = dict["8"]; // "foobar"
If you use the dynamic implementation here:
https://github.com/b9chris/GracefulDynamicDictionary
You can get the Dictionary right from the implementation. One advantage to using the above implementation (written for an answer to another SO question), is you can shift easily between the specific implementation and dynamic, like so:
dynamic headers = new DDict();
headers.Authorization = token;
if (doesNeedSiteId)
headers.SiteId = siteId;
await post(headers);
}
protected async Task post(DDict headers)
{
var dict = headers.GetDictionary(); // Dictionary<string, object>
In the above, the headers collection is conveniently created as a dynamic, but, the underlying specific implementation is DDict, and the post() method accepts it even though you've declared it as dynamic and used its features.

Assign the literal string as a property of a dynamic object during runtime and access it

How can I assign the fieldname of a sqldatareader during runtime dynamically to a dynamic object?
Lets assume I have read the fieldname of a SqlDataReader into a variable:
string sqlDataReaderFieldNameStringVariable = reader.GetName(index);
I can not say:
dynamic dyn = new ExpandoObject();
dyn.sqlDataReaderFieldNameStringVariable = "test";
How can I do that?
UPDATE:
still time to get a point ;-) I add my dyn object to a List of type ExpandoObject which is the return value of a method. When I access the list via data[0].test property does not exist while compile time ???
When I do this outside of the method returning the List:
dynamic bla = (ExpandoObject)data[0];
String shit = bla.Name;
Why do I have to cast it? Any workaround? Thanks Jon.
You have to cast your ExpandoObject dyn to IDictionary<string, object> first to do that:
dynamic dyn = new ExpandoObject();
var dynDict = dyn as IDictionary<string, object>;
dynDict[sqlDataReaderFieldNameStringVariable] = "test";
For most dynamic objects, it's tricky. Doable (using IDynamicMetaObjectProvider) but tricky. If you're really using ExpandoObject, it's simple because that implements IDictionary<string, object>:
dynamic dyn = new ExpandoObject();
var dictionaryView = (IDictionary<string, object>) dyn;
dictionaryView[sqlDataReaderFieldNameStringVariable] = "test";

How do I reference a field in an ExpandoObject dynamically?

Is there a way to dynamically access the property of an expando using a "IDictionary" style lookup?
var messageLocation = "Message";
dynamic expando = new ExpandoObject();
expando.Message = "I am awesome!";
Console.WriteLine(expando[messageLocation]);
You have to cast the ExpandoObject to IDictionary<string, object> :
var messageLocation = "Message";
dynamic expando = new ExpandoObject();
expando.Message = "I am awesome!";
var expandoDict = (IDictionary<string, object>)expando;
Console.WriteLine(expandoDict[messageLocation]);
(Also your expando variable must be typed as dynamic so property access is determined at runtime - otherwise your sample won't compile)

Categories