How can i convert an array in Json string to c# object? - c#

I have a json return result like the following:
Json =
{
"Id":"12345",
"FirstName":"Bob",
"LastName":"Builder",
"Links":[]
}
Links can have a list of objects of type LinkService, i want to cast even if the array is empty , so in c# i get an empty array.
I do the following
var token = JObject.Parse(Json);
var Id = token.Value<string>("Id");
var fname = token.Value<string>("FirstName");
var lbname = token.Value<bool>("LastName");
var links = JsonSerializer.Deserialize<List<LinkService>>(token.Value<Array>("Links"));
Issue is that it says cant convert System.Array to Newtonsoft.Json.JsonReader

You can convert the jToken to an object using the ToObject method:
var links = token["Links"].TObject<List<LinkService>>();

Related

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;

Convert JSON to a DataTable directly

I have a Json(gridModel) which could be a Json array or simple Json String. I want to serialize it to a List which matches the Json. Using Newtonsoft.Json.
JArray jGridModel = JArray.Parse(gridModel);
List<ClassName> colModel = jGridModel.ToObject<List<ClassName>>();
This works fine if the gridModel is a JSON array, but if its a single JSON, it throws an error. Please assist.
Another question. Instead of converting it to List, Is there a way to convert the JSONArray to DataTable directly, please help. Thanks.
You need to check if the object generated by the code JArray jGridModel = JArray.Parse(gridModel); is a a Type of List See updated code below:
JArray jGridModel = JArray.Parse(gridModel);
// declare your output variable
List<ClassName> colmodel = new List<ClassName>();
// use var so it can accept any output type
var outputObject = jGridModel.ToObject<List<ClassName>>();
// check the type of the output
if (outputObject is ClassName){
colmodel.Add(outputObject);
}
else{
colmodel = outputObject;
}
//colmodel is your output which is always a List<ClassName> type

Parse JSON object in C# without using class

I have two string values in a JSON object. I want to call this method in same class and use the values without using class.
I am using the following method:
public JsonResult Details()
{
return Json(new { Data = "DisplayName", result = "UniqueName" });
}
I need to use this data and result value in another method.
I am getting the value like:
var Details = JsonConvert.SerializeObject(Details());
My output is:
{
\"ContentEncoding\": null,
\"ContentType\": null,
\"Data\": {
\"Data\": \"DisplayName\",
\"result\": \"UniqueName\"
},
\"JsonRequestBehavior\": 1,
\"MaxJsonLength\": null,
\"RecursionLimit\": null
}
How do I get the data and result value from this?
The method which you are using (i.e:)
public JsonResult Details()
{
return Json(new { Data = "DisplayName", result = "UniqueName" });
}
returns a JsonResult object which has a property named Data, i.e Details().Data, which contains the data your object contains. So in order to get your object's Data and result values, you need to serialize it again.
This is the full solution:
JsonResult json = Details(); // returns JsonResult type object
string ser = JsonConvert.SerializeObject(json.Data); // serializing JsonResult object (it will give you json string)
object dec = JsonConvert.DeserializeObject(ser); // deserializing Json string (it will deserialize Json string)
JObject obj = JObject.Parse(dec.ToString()); // it will parse deserialize Json object
string name = obj["Data"].ToString(); // now after parsing deserialize Json object you can get individual values by key i.e.
string name = obj["Data"].ToString(); // will give Data value
string name = obj["result"].ToString(); // will give result value
Hope this helps.
By looking at JsonConvert.SerializeObject, I guess you are using NewtonSoft dll. In that you have JObject.Parse under Newtonsoft.Json.Linq which you can import (using Newtonsoft.Json.Linq;). You can parse that json string as
var details = JObject.Parse(your_json_string);
This will give you JObject and you can get the details as
var data = details["Data"].ToString();
JsonResult already stores the object for you, under Data. It has not been serialized yet, it simply indicates to the MVC framework to serialize it to JSON when responding to a web request.
var details = Details().Data;
Of course, this will be typed as an object - which isn't too useful. You can cast it back to the anonymous type like this:
private T CastToAnonymous<T>(object obj, T anonymousType)
{
return (T)obj;
}
var details = CastToAnonymous(Details().Data,
new { Data = string.Empty, result = string.Empty });
And then you can use it like...
var data = details.Data;
var result = details.result;
And it will be type-safe.

Newtonsoft JSON deserialize to type from list

I have created a list of types like this:
var executingAssembly = Assembly.GetExecutingAssembly();
var referencedAssemblies = executingAssembly.GetReferencedAssemblies();
var assembly = referencedAssemblies.Single(x => x.Name.Equals("X.Y.Z"));
var messagesAssembly = Assembly.Load(assembly);
var types = messagesAssembly.GetTypes();
var selectedTypes = from t in types
where t.Namespace.Contains("X.Y.Z.K")
select t;
and I need to convert some json data into one of these types. How do I figure out which one is the correct one?
I have tried the following:
var jsonData = File.ReadAllText(filePair.FullPath);
foreach(var type in selectedTypes)
{
var correctObject = JsonConvert.DeserializeObject(jsonData, type);
}
Which just converts it to the first type in the list
I have also tried with the template method
var jsonData = File.ReadAllText(filePair.FullPath);
foreach(var type in selectedTypes)
{
var correctObject = JsonConvert.DeserializeObject<type>(jsonData);
}
Which "Cannot resolve symbol 'type'.
Is it possible to convert it to a the correct type in selectedTypes?
I ended up using ".NET's fastest JSOn Serializer by ServiceStack".
It has a method ServiceStack.Text.JsonSerializer.DeserializeFromString(string value, Type type) which worked perfectly.

JObject how to read values in the array?

This is the json string:
{"d":[{"numberOfRowsAdded":"26723"}]}
string json = DAO.getUploadDataSummary();
JObject uploadData = JObject.Parse(json);
string array = (string)uploadData.SelectToken("d");
How do I change the code to reader the values in 'numberOfRowsAdded?
JObject uploadData = JObject.Parse(json);
int rowsAdded = Convert.ToInt32((string)uploadData["d"][0]["numberOfRowsAdded"])
You need to cast to JArray:
string json = "{\"d\":[{\"numberOfRowsAdded\":\"26723\"}]}";
JObject parsed = JObject.Parse(json);
JArray array = (JArray) parsed["d"];
Console.WriteLine(array.Count);
You can cast your JObject as a dynamic object.
You can also cast your array to JArray object.
JObject yourObject;
//To access to the properties in "dot" notation use a dynamic object
dynamic obj = yourObject;
//Loop over the array
foreach (dynamic item in obj.d) {
var rows = (int)item.numberOfRowsAdded;
}
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

Categories