How to deserialize JSON (snake_case) to dynamic (PascalCase)? - c#

This code works fine:
string json = #"{""MyProperty"" : ""bar""}";
var payload = JsonConvert.DeserializeObject<dynamic>(json);
string typedProperty = payload.MyProperty; //contains "bar"
Let's try to do the same with snake_case JSON. We add a SnakeCaseNamingStrategy which is actually a recommended way to handle snake_case.
_snakeSettings = new JsonSerializerSettings()
{
ContractResolver = new UnderscorePropertyNamesContractResolver()
};
public class UnderscorePropertyNamesContractResolver : DefaultContractResolver
{
public UnderscorePropertyNamesContractResolver()
{
NamingStrategy = new SnakeCaseNamingStrategy();
}
}
Then, apply the settings to the DeserializeObject call. In case of deserialization to a static type, those settings are successfully applied to snake_case JSON:
string snakeJson = #"{""my_property"" : ""bar""}";
var payload = JsonConvert.DeserializeObject<Payload>(snakeJson, _snakeSettings);
string typedProperty = payload.MyProperty; //contains "bar"
OK, switch the target type to dynamic:
var payload = JsonConvert.DeserializeObject<dynamic>(snakeJson, _snakeSettings);
string typedProperty = payload.MyProperty; //is null
string wrongProperty = payload.my_property; //is not null
As you see, _snakeSettings are ignored this time. I guess this is a bug. Does any workaround exist to do JSON (snake_case) -> dynamic (PascalCase) deserialization?
Environment:
<TargetFramework>netcoreapp1.1</TargetFramework>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />

When you call JsonConvert.DeserializeObject<dynamic> it acts the same way as JsonConvert.DeserializeObject<JObject>. JObject is not a real result of the deserialization, but some intermediate state of your data, It is closer to readers than to objects. E.g. it allows you to deserialize only part of a JSON
So seems like JsonConvert.DeserializeObject<dynamic> creates not a result object but a reach, functional reader for the JSON data. I suppose, that's why it shows you data as it was without any post processing
I suppose it's better to direct that question to a "Newtonsoft.Json" developers.

Related

String date property of object is deserialized to another format even though it should remain unchanged [duplicate]

Here is the code:
string s = "2012-08-08T01:54:45.3042880+00:00";
JObject j1 = JObject.FromObject(new
{
time=s
});
Object o = j1["time"];
We can check that o is string and equals "2012-08-08T01:54:45.3042880+00:00"
Now we transfer j1.ToString() to another program, which is
{
"time": "2012-08-08T01:54:45.3042880+00:00"
}
then at the other program, try to parse it back to JObject, which is
JObject j2 = JObject.Parse(j1.ToString());
Object o2 = j2["time"];
Now, if we check o2, o2's type is Date, o2.ToString() is 8/7/2012 9:54:45 PM.
My question is:
Is there is way to disable the Date deserialization for JObject.Parse , and just get the raw string?
Thanks in advance
When parsing from an object to JObject you can specify a JsonSerializer which instructs how to handle dates.
JObject.FromObject(new { time = s },
new JsonSerializer {
DateParseHandling = DateParseHandling.None
});
Unfortunately Parse doesn't have this option, although it would make sense to have it. Looking at the source for Parse we can see that all it does is instantiate a JsonReader and then passes that to Load. JsonReader does have parsing options.
You can achieve your desired result like this:
using(JsonReader reader = new JsonTextReader(new StringReader(j1.ToString()))) {
reader.DateParseHandling = DateParseHandling.None;
JObject o = JObject.Load(reader);
}
For background, see Json.NET interprets and modifies ISO dates when deserializing to JObject #862, specifically this comment from JamesNK: I have no plans to change it, and I would do it again if give the chance.
You can accomplish this using JsonConvert.DeserializeObject as well, by using JsonSerializerSettings:
string s = "2012-08-08T01:54:45.3042880+00:00";
string jsonStr = $#"{{""time"":""{s}""}}";
JObject j1 = JsonConvert.DeserializeObject<JObject>(jsonStr, new JsonSerializerSettings {DateParseHandling = DateParseHandling.None});

how to deserialize an anonymus object in c# [duplicate]

Is it possible to return a dynamic object from a json deserialization using json.net? I would like to do something like this:
dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);
Json.NET allows us to do this:
dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");
Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);
Output:
1000
string
6
Documentation here: LINQ to JSON with Json.NET
See also JObject.Parse and JArray.Parse
As of Json.NET 4.0 Release 1, there is native dynamic support:
[Test]
public void DynamicDeserialization()
{
dynamic jsonResponse = JsonConvert.DeserializeObject("{\"message\":\"Hi\"}");
jsonResponse.Works = true;
Console.WriteLine(jsonResponse.message); // Hi
Console.WriteLine(jsonResponse.Works); // True
Console.WriteLine(JsonConvert.SerializeObject(jsonResponse)); // {"message":"Hi","Works":true}
Assert.That(jsonResponse, Is.InstanceOf<dynamic>());
Assert.That(jsonResponse, Is.TypeOf<JObject>());
}
And, of course, the best way to get the current version is via NuGet.
Updated (11/12/2014) to address comments:
This works perfectly fine. If you inspect the type in the debugger you will see that the value is, in fact, dynamic. The underlying type is a JObject. If you want to control the type (like specifying ExpandoObject, then do so.
If you just deserialize to dynamic you will get a JObject back. You can get what you want by using an ExpandoObject.
var converter = new ExpandoObjectConverter();
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
I know this is old post but JsonConvert actually has a different method so it would be
var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);
Yes you can do it using the JsonConvert.DeserializeObject. To do that, just simple do:
dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);
Note: At the time I answered this question in 2010, there was no way to deserialize without some sort of type, this allowed you to deserialize without having go define the actual class and allowed an anonymous class to be used to do the deserialization.
You need to have some sort of type to deserialize to. You could do something along the lines of:
var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());
My answer is based on a solution for .NET 4.0's build in JSON serializer. Link to deserialize to anonymous types is here:
http://blogs.msdn.com/b/alexghi/archive/2008/12/22/using-anonymous-types-to-deserialize-json-data.aspx
If you use JSON.NET with old version which didn't JObject.
This is another simple way to make a dynamic object from JSON:
https://github.com/chsword/jdynamic
NuGet Install
PM> Install-Package JDynamic
Support using string index to access member like:
dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);
Test Case
And you can use this util as following :
Get the value directly
dynamic json = new JDynamic("1");
//json.Value
2.Get the member in the json object
dynamic json = new JDynamic("{a:'abc'}");
//json.a is a string "abc"
dynamic json = new JDynamic("{a:3.1416}");
//json.a is 3.1416m
dynamic json = new JDynamic("{a:1}");
//json.a is integer: 1
3.IEnumerable
dynamic json = new JDynamic("[1,2,3]");
/json.Length/json.Count is 3
//And you can use json[0]/ json[2] to get the elements
dynamic json = new JDynamic("{a:[1,2,3]}");
//json.a.Length /json.a.Count is 3.
//And you can use json.a[0]/ json.a[2] to get the elements
dynamic json = new JDynamic("[{b:1},{c:1}]");
//json.Length/json.Count is 2.
//And you can use the json[0].b/json[1].c to get the num.
Other
dynamic json = new JDynamic("{a:{a:1} }");
//json.a.a is 1.
Yes it is possible. I have been doing that all the while.
dynamic Obj = JsonConvert.DeserializeObject(<your json string>);
It is a bit trickier for non native type. Suppose inside your Obj, there is a ClassA, and ClassB objects. They are all converted to JObject. What you need to do is:
ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();

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 to deserialize JSON object with json.net

StreamReader qryTmpltStream = new StreamReader(tmpltPath + "templates.json");
JsonTextReader qryTmpltReader = new JsonTextReader(qryTmpltStream);
JsonSerializer qryTmpltSrlzr = new JsonSerializer();
object jsonObject = qryTmpltSrlzr.Deserialize(qryTmpltReader);
var tplts = JsonConvert.DeserializeObject<JSONRepClass>(jsonObject);
In above code I'm trying to read in a json file then deserialize it into a class. The problem is, this: JsonConvert.DeserializeObject wants a string, but the Deserailize method call before it returns an object.
I tried casting to string and ToString(), but no go.
Anyone see what I'm missing here?
Try this, just read the json file contents into a string and deserialize it using Json.Net
var jSonString = File.ReadAllText(tmpltPath + "templates.json");
var tplts = JsonConvert.DeserializeObject<JSONRepClass>(jsonString);
This is the simplest way to use JSON.net to turn a json string into a strongly typed class.
YourClass myclass = new YourClass();
JsonConvert.PopulateObject(yourstring,myclass);

Serialize string to JSON without \0027

A fairly straightforward question. I have the following code
var json = new JavaScriptSerializer();
var test = json.Serialize("'");
Now, Visual Studio local variable watch shows that test contains a string of value "\"\\u0027\"". Is it possible, using build in ASP.NET to make Serialize(); return serialized string without \0027 format?
The desired result for test would be "\"\'\""
Thanks!
As the commenters mentioned, this really shouldn't matter because \u0027 literally represents a single quote in Javascript.
However, if this bothers you, you may want to try using JSON.NET, which leaves single-quotes in encoded strings as they are.
Try the following
var json = JsonConvert.SerializeObject(obj);
You have to use this expression to replace your JSON string after it's serialized. Here is a sample of my code along with a function I use when giving a json output.
string json = obj.ToJSON();
json = System.Text.RegularExpressions.Regex.Unescape(json);
File.WriteAllText("<DirectoryFile>.json", json);
public static string ToJSON(this object obj)
{
var serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(obj);
}

Categories