Accessing a certain variable inside a json without creating a deserialization class - c#

I currently have a json string that looks like this
{
"strA":"somestr",
"strB":{
"strB":"String B",
"strC":"String C",
"sections":[
{
"strD":"...",
"str$":"...",
"myArray":[
{
"name":"xxxx",
"value":"xxxx"
}
]
}
]
}
}
Now the content of this json could change however strB will always be where it is. The value of strB can always change. I would like to get the value of strB as string. I tried doing this
var info = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(str);
string strB = info["strB"].ToString();
but that seems to be wrong . Any idea on how I can extract strB value from this json as a string without creating a deserialization class .

You can use JObject and run linq on it.
JObject json = JObject.Parse(jsonstring);
// access the value like this
json["strB"]
Find some very good example: https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm

Related

Read List<double> from Json via Newtonsoft in C#

I would like to read a JSON string via the Newtonsoft Json library. It works fine for any basic datatype, but it does not work for a List<double> or any List for that matter.
The test application looks like the following:
static void main()
{
string jsonString = #"
{
'name': 'set1',
'Xvv': {
'parameter': 'hByT',
'values': '[1,2,3]'
}
}";
JObject Json = JObject.Parse(jsonString);
var name = Json["name"].ToString();
var data = Json["Xvv"]["values"].Value<List<double> >(); // Raises error
}
The last line throws the following exception:
System.InvalidCastException: Invalid cast from 'System.String' to 'System.Collections.Generic.List
Is there a way to access the data directly as a List<double>?
In the example JSON you've provided, values is a string. A proper JSON array would be
'values': [1,2,3]
Anyway, after changing the string to the array, .Value<List<double>>() would throw an exception, that a JArray cannot be cast to a JToken - unfortunately I do not really know, why it does not work.
However, JToken.ToObject<T> does the trick, it
Creates an instance of the specified .NET type from the JToken
(see the documentation for ToObject)
With the line
var data = Json["Xvv"]["values"].ToObject<List<double>>();
you can cast the array correctly.
If an IEnumerable would be fine for you, too, you could also use
var data = Json["Xvv"]["values"].Values<double>();

Dynamic variable not working in C# with Json.Net

Can anyone tell me why I get an error when trying to output"dJson2.Type" in the code below?
string Json1= #"[{'Id':1, 'FirstName':'John', 'LastName':'Smith'}, {'Id':2, 'FirstName':'Jane', 'LastName':'Doe'}]";
dynamic dJson1= JsonConvert.DeserializeObject(Json1);
Console.WriteLine(dJson1.GetType());
Console.WriteLine(dJson1.Type);
string Json2 = #"{'Id':1, 'FirstName':'John', 'LastName':'Smith'}";
dynamic dJson2 = JsonConvert.DeserializeObject(Json2);
Console.WriteLine(dJson2.GetType());
Console.WriteLine(dJson2.Type);
The program dies on the Console.WriteLine(dJson2.Type) statement. The output of the program is...
Newtonsoft.Json.Linq.JArray
Array
Newtonsoft.Json.Linq.JObject
(should say Object here, I think)
Inspecting the local variables, dJson2 has a "Type" property with value "Object".
This is because JObject behaves similarly as System.Dynamic.ExpandoObject. Try to change your example to:
string Json2 = #"{'Id':1, 'FirstName':'John', 'LastName':'Smith'}";
dynamic dJson2 = JsonConvert.DeserializeObject(Json2);
dJson2.Type = "mynewfield";
Console.WriteLine(dJson2.GetType());
Console.WriteLine(dJson2.Type);
If you want to get property of underlying type you need to cast it (to JToken or JObject), otherwise requested property will be searched in
IDictionary<string, JToken> that JObject implements.
This example may help:
dynamic oobj = new JObject();
oobj.Type = "TEST";
Console.WriteLine(oobj.Type);
Console.WriteLine(((JObject)oobj).Type);

Cannot access properties after JSON deserialization into dynamic

I'm having some issues accessing dynamic properties after JSON deserialization. Here is the JSON:
{
"user" : {
"511221" :{
"timestamp" : 1403365646384,
"version" : -81317051,
"email" : "user#name.com",
"name" : "My Name",
"structures" : [ "structure.62dd1ff1-f96b-22e3-8d4e-22000c20725r" ]
}
},
}
There's actually two problems here. First is that "511221" changes for each user. This is given when authenticating. I can't create a user class and then create another class which name keeps changing.
Also, it's a number. AFAIK, there is no way to have a class name as a number. What are my options here? I cannot control what gets returned by the API.
So instead of deserialization into a predefined class, I have a dynamic, like this:
dynamic jsonObject = JsonConvert.DeserializeObject(response);
I want to be able to do this:
string[] structures = jsonObject.user.(authInfo.userid).structures;
In words, I want (authInfo.userid) to input the user id as a string above, however this does not seem possible. I have also tried reflection:
private static object ReflectOnPath(object o, string path)
{
object value = o;
string[] pathComponents = path.Split('.');
foreach (var component in pathComponents)
{
Type type = value.GetType();
System.Reflection.PropertyInfo pi = type.GetProperty(component);
//pi is null here, I have no idea why
value = pi.GetValue(value);
}
return value;
}
So it could be called like this to do the same as shown above:
string[] structures = ReflectOnPath(jsonObject, "user." + authInfo.userid + ".structures") as string[];
However, when this is called, GetProperty() on type (JObject) is null. I know the property "user" exists, but why can't I access it?
You can deserialize your JSON to JObject instead of dynamic, then you can access the property by property name dynamically, for example :
JObject jObject = JsonConvert.DeserializeObject<JObject>(response);
var user = "511221";
var structures = jObject["user"][user]["structures"][0];
//given JSON input as in this question,
//following line will print "structure.62dd1ff1-f96b-22e3-8d4e-22000c20725r"
Console.WriteLine(structures);

Newtonsoft.Json SerializeObject without escape backslashes

Given the code:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
The output is below:
"{\"Bar\":\"something\"}"
When debugging a large json document it is hard to read - using the built in features of Newtonsoft.Json (not regex or hacks that could break things) is there any way to make the output a string with the valie:
{Bar: "something"}
If this happens to you while returning the value from a WebApi method, try returning the object itself, instead of serializing the object and returning the json string. WebApi will serialize objects to json in the response by default; if you return a string, it will escape any double quotes it finds.
So instead of:
public string Get()
{
ExpandoObject foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
return json;
}
Try:
public ExpandoObject Get()
{
ExpandoObject foo = new ExpandoObject();
foo.Bar = "something";
return foo;
}
Try the JToken.Parse method. I've found that even though when I view JSON objects in the debugger and they are correct, when I go to manipulate them they end up being converted to literals (i.e. backslashes are added). The JToken.Parse method seems to avoid this.
var token = JToken.Parse(text);
So in the case of the original question it would be something like:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
var token = JToken.Parse(json);
//Do stuff with token -- not json string
In my case specifically the issue was that using JObject.Add(json) would not recognize that my string was json and just insert the entire string as a single property. Once converted into a Jtoken however the JSON was interpreted correctly.
What you see in debugger when looking at the json value is the string value that you should use in a C# file to obtain the same value.
Indeed you could replace
dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
with
string json = "{\"Bar\":\"something\"}";
without changing the program's behaviour.
Thus, to obtain a different value, you should change how JsonConvert works, but JsonConvert conforms to the JSON standard, thus forget it!
If you are not actually serializing ExpandoObject (nor any other sealed class out of your control), you can use the DebuggerDisplayAttribute on the types that you are serializing in json, to define how the object will be shown during debug (in your code, the foo instance).
But a string is a string and VisualStudio is right: double-quotes must be escaped.
Old question but I found this,
In my case, I was looking at the JSON string in a debugger and I found that was adding the escaping.
And when I printed JSON to console, it was without escape characters. Hope it helps.
Instead of using Newstonsoft.Json you should employ the JavaScriptSerializer.Serialize Method:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
var js = new JavaScriptSerializer( );
string json = js.Serialize(foo);
This method produces exactly the output you are looking for. I read about it here.
Its Just simple make the return IHttpActionResult and return the object
public IHttpActionResult Get()
{
ExpandoObject foo = new ExpandoObject();
foo = //query result
return ok(foo)
}
Hey I Just simply write out put to a file
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(#"jsonGonna.txt", true))
{
file.WriteLine(json);
}
now just run the program and you will get without black slash and it good for big programs where you need to save JSON multiple times
Actually it has nothing to do with serializer. It's just because c# don't have single and double quotes concept like Javascipt does. So it can't show string with double quotes without escaping them.
But if you want to put string into html/ cshtml without any escapes you just need to tell compliler that like so:
window.MYVAR = JSON.parse('#Html.Raw(ViewBag.MyStringFromCSharp)');
In case you're getting your data from a controller view method in such a format and finding it difficult to work with in JavaScript. Below is an easy work around:
const CleanUpDifficultJSonData = difficultJSonData => {
const dummyElement = document.createElement('div');
dummyElement.innerHtml = difficultJSonData;
const cleanJSonData = JSON.parse(dummyElement.innerHtml);
return cleanJSonData;
};
const difficultJSonData = "{\"Bar\":\"something\"}";
console.log('cleanJSonData: ',
CleanUpDifficultJSonData(difficultJSonData));
[HttpGet]
public object Get(int id)
{
object result = "";
var db = new dbEntities();
var EO = new System.Dynamic.ExpandoObject() as IDictionary<string, Object>; //needed to return proper JSON without escape slashes
try
{
IEnumerable<usp_GetComplaint_Result> aRow = db.usp_GetComplaint(id);
string DBL_QUOTE = new string(new char[] { '"' });
result = "{";
foreach (usp_GetComplaint_Result oneRow in aRow)
{
System.Reflection.PropertyInfo[] properties = typeof(usp_GetComplaint_Result).GetProperties();
foreach(System.Reflection.PropertyInfo property in properties)
{
var vValue = property.GetValue(oneRow) == null ? "null" : property.GetValue(oneRow);
EO.Add(property.Name,vValue);
}
break;
}
}
catch (Exception ex)
{
result = ex.Message;
EO.Add("Error", result);
}
finally
{
db.Dispose();
}
return Ok(EO);
}

How can I access this field on json?

I've converted a XML into a JSON:
var json = JsonConvert.SerializeXmlNode(doc);
This is the result:
"author": {
"name": "Hey Guappo",
"yt:userId": "asfajgf346346fghsdgsWfiqcfr1pfQ"
}
and I'd like to access to the yt:userId.
I can't do this in .NET:
dynamic objectParsed = JObject.Parse(json);
var userID= (string)objectParsed.entry.author.yt:userId;
because of :. So how can I manage Namespace in JSON? I have:
var yt = XNamespace.Get("http://gdata.youtube.com/schemas/2007");
but I don't know how to apply it...
Try this:
JObject json = JObject.Parse(json);
string userId = json["author"]["yt:userId"].ToString();
This WILL work with the dynamic just fine. You don't have to use a JObject. In addition, I've highlighted the fact that you can use . notation UP TO your "yt:userId", at which point you need to index by string value.
dynamic objectParsed = JObject.Parse(json);
string userId = json.author["yt:userId"].ToString();
There is really no reason to NOT use a JObject, as Tobberoth pointed out, but there is also no technical restriction on using a dynamic if you prefer.
As a side note, avoid using an explicit cast to string with (string). Always use ToString().

Categories