Deserialize JSON string into class with reflection - c#

I'm trying to deserialize a JSON string into a custom class. I have to use reflection. I have a dictionary that I serialize, send over to an HttpPut method, deserialize the JSON string, and read the dictionary fields. Here's what I have so far:
I'm putting values into the Dictionary like this:
Dictionary<string, object> valuesToUpdate = new Dictionary<string, object>();
Person p = new Person();
p.personName = "OrigName";
p.age = "25";
p.isAlive = true;
valuesToUpdate.Add("Person", p);
valuesToUpdate.Add("Length", 64.0);
I'm using JSON to serialize it like this:
string jsonString = JsonConvert.SerializeObject(valuesToUpdate);
I then take the jsonString and send it over to a REST API PUT method. The PUT method updates various variables on a custom object based on the Key values in the dictionary using reflection (In this example I'm updating customObject.Person and customObject.Length).
The PUT call deserializes the jsonString like this:
Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
I iterate through newFields and want to use reflection to update customObject's "Person" class. This is my HttpPut method that reads the jsonString:
[HttpPut("/test/stuff")]
public string PutContact([FromBody]dynamic jsonString)
{
Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
foreach (var field in newFields)
{
Console.WriteLine("\nField key: " + field.Key);
Console.WriteLine("Field value: " + field.Value + "\n");
PropertyInfo propInfo = typeof(Contact).GetProperty(field.Key);
Type propertyType = propInfo.PropertyType;
var value = propInfo.GetValue(contactToUpdate, null);
if (propertyType.IsClass)
{
propInfo.SetValue(contactToUpdate, field.Value, null);
}
}
}
This generates the error:
Object of type Newtonsoft.Json.Linq.JObject' cannot be converted to type 'Person';
I've also tried using JSON's PopulateObject method but it returned this error:
Newtonsoft.Json.JsonSerializationException: Cannot populate JSON object onto type 'Person'. Path 'personName', line 1....
So basically, how can you go about taking a JSON string, converting it to a class (in my case the 'Person' class), and setting it to customObject's Person field with reflection?

if (propertyType.IsClass)
{
propInfo.SetValue(contactToUpdate, ((JObject)field.Value).ToObject(propertyType), null);
}

Related

Custom JSON field names with Newtonsoft as defined by a variable [duplicate]

I have a method which accepts a key and a value. Both variables can have a dynamic content.
key => is a dynamic string which can be everything like e.g. "LastSentDate"
value => is an object which can be everything like e.g. "2014-10-10"
As key is a dynamic value like "LastSentDate" or whatever key is passed to the method then I want that the json property is the value of the key string and not literally key itself...
public void SetRowVariable(string key, object value)
{
var obj = new { key = value }; // key property is literally taken maybe anonym object is not a good idea?
string jsonString = JsonConvert.SerializeObject(obj);
// jsonString should have that output => "{ "LastSentDate": "2014-10-10" }"
}
How do I have to serialize the obj that I get the wished output?
It must also be possible that the "key" property can contain special chars like "!"ยง$%&/()=?"`
I am using .NET 3.5 sadly.
You could use a JObject (in Newtonsoft.Json.Linq):
var obj = new JObject();
obj[key] = JToken.FromObject(value);
string jsonString = obj.ToString();
You may try using a Dictionary<string, object>:
public void SetRowVariable(string key, object value)
{
var obj = new Dictionary<string, object>();
obj[key] = value; // Of course you can put whatever crap you want here as long as your keys are unique
string jsonString = JsonConvert.SerializeObject(obj);
...
}

How to deserialize json where type of properties not fixed - can be empty string or an object, please suggest. how to handle this situation?

I have to process the JSON object returned by an API response.
I tried by creating expando object and than adding all the properties to it.
and than copying the value to it.
dynamic dPropertyLinkValue = new ExpandoObject();
dPropertyLinkValue.link = "";
dPropertyLinkValue.value = "";
I am expecting a better way to do this, without expando object.
You can deserialize JSON by casting it to dynamic object. Please refer below sample:
Here deserializing Json to dynamic object and after that loop through its properties and in that you can check you value that whether it is object or not.
string jsonText = "{a:'testString',b:{'prop1':'value1'}}";
var jObj = JsonConvert.DeserializeObject<dynamic>(jsonText);
foreach (JProperty property in jObj)
{
string text = property.Name + " : " + property.Value;
//Here you can check whether property.Value is Jobject or any other value
}

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.

Getting values out of the JSON object in C#

I have a JSON structure like below.
{"name":"user1","param":{"showid":"test"}}
I will pass the value of JSON structure to a program where the values of the JSON object will be fetch out.
But the key values will differ for each JSON object.
SO i couldnt create a structure for the JSON object to retrieve the values.
ie : The next time the JSON object may be like below.
{"name1":"user2","param1":{"showname":"test1"}}
How to iterate the key value pair from the JSON structure in c#?
You can use System.Web.Script.Serialization.JavaScriptSerializer (System.Web.Extensions.dll) and load it into a datatype "dynamic", then you can access the properties like a dictionary.
Or you can use reflection to find the available properties/fields, and get a field's/property's value.
public static Dictionary<string, object> ToPropertyDictionary(this object obj)
{
var dictionary = new Dictionary<string, object>();
foreach (var propertyInfo in obj.GetType().GetProperties())
if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0)
dictionary[propertyInfo.Name] = propertyInfo.GetValue(obj, null);
return dictionary;
}

Categories