Deserialize nested properties - servicestack

I am using ServiceStack.Text to deserialize a response like so:
var obj = JsonObject.Parse(response);
The problem is that it only deserializes top level properties.
I tried playing around with some settings like:
JsConfig.Init(new ServiceStack.Text.Config
{
IncludeTypeInfo = true,
ConvertObjectTypesIntoStringDictionary = true
});
but doesn't change anything.
How do I fully deserialize response including nested objects without a concrete type? (my goal is to be able to access deep values by string)

If you want to parse arbitrary JSON with ServiceStack, use JSON.parse() from ServiceStack.Common NuGet package:
var obj = JSON.parse(response);
ServiceStack.Text JSON Serializers is primarily for deserializing JSON into Typed models.

Related

use nodejs var as json object statement?

how do I use a nodejs var inside a json statement, I dont realy have the required vocabulary to explain but here is my simplifyed code:
test.json:
{
"test1":["test1.1", "test1.2"],
"test2":["test2.1", "test2.2"]
}
test.js:
const json = require("./test.json")
function myFunction(TYPE){
return(json.TYPE[0])
}
console.log(myFunction("test1"))
as I use the "type" var it tries to uses it as an json statement or object but obviously there is no "type" there only is "test1" and "test2" but it interprets as "type" instead
Brackets to access the variable key should work
function myFunction(TYPE){
return(json[TYPE][0])
}
In JavaScript, json objects are pretty much same as plain JS objects. You need to use string as an index to access properties:
// This could be your json file, its almost the same
// Just require it like you did instead of using const JSON like i am
const json = {
"test1":["test1.1", "test1.2"],
"test2":["test2.1", "test2.2"]
}
function myFunction(TYPE){
// Access the json by using keyword directly as index string
return(json[TYPE])
// because TYPE is a string, TYPE[0] would mean first letter of TYPE string
}
function myFunctionDeeper(TYPE){
// To access a field and array in that field
return(json[TYPE][0])
}
console.log(myFunction("test1"))
console.log(myFunctionDeeper("test1"))
// example for what happens when accessing string by index
console.log("test1"[0])
Read more about objects here

SyntaxError: Unexpected token o in JSON at position 1 - Simple Error

I am currently taking a course on node.js and I am receiving this error:
SyntaxError: Unexpected token o in JSON at position 1
The code that I anticipate is giving me this problem is:
const loadNotes = function() {
// try {
//This code is exactly the same as the video's
const dataBuffer = fs.readFileSync('notes.json')
const dataJSON = JSON.toString(dataBuffer)
return JSON.parse(dataJSON)
//} catch(e) {
//return []
// }
I checked similar answers, but they seemed more complex, and as such, I was unable to fix the problem using them.
Your JSON.toString() is not returning what you think it is.
toString() is returning a string representation of the JSON object.
The result is: [object JSON]
That is not a proper JSON string so JSON.parse() fails.
So, there are two problems:
You are incorrectly using the prototype toString() method
You are feeding a non-JSON string to JSON.parse()
Explanation:
Firstly, as was stated in the comments above, there is no toString() method defined in the JSON object. .toString() in the JSON object's prototype chain does do something when you call it but the result is a string representation of the JavaScript JSON object, not the JSON object you are attempting to read from your file. You really want to use JSON.stringify() instead of toString().
Here's the explanation in MDN:
Every object has a toString() method that is automatically called when
the object is to be represented as a text value or when an object is
referred to in a manner in which a string is expected. By default, the
toString() method is inherited by every object descended from Object.
If this method is not overridden in a custom object, toString()
returns "[object type]", where type is the object type.
So, you can call toString() on any object in JavaScript and get [object Object]. But that's not what you want. So, don't use toString(). It's not doing what you think it's doing.
Secondly, be sure that you are trying to parse a real JSON string and not trying to parse a JavaScript object. There is a significant difference between the two.
Take a look at this code:
let dataJS = {
key: "value"
}
Above, I have defined a JavaScript object called dataJS.
I can convert the dataJS JavaScript object into a JSON object by using the JSON.stringify() method like this:
let dataJSON = JSON.stringify(dataJS);
The JSON.stringify() method expects a JavaScript object and will return a JSON string. I have assigned the resulting JSON string to dataJSON. Now, I have two things: a JavaScript object called dataJS and a JSON string called dataJSON.
I can print the contents of these two things like this:
console.log("JSON:\n", dataJSON)
console.log("JS:\n", dataJS)
Notice carefully how the two appear. You'll see this:
JSON:
{"key":"value"}
JS:
{ key: 'value' }
Do you see the difference in between the JSON string and the JavaScript object?
The JSON string has double-quotes around the key and values. The JavaScript object does not have any quotes around the key and single-quotes around the value.
These make JSON strings and JavaScript objects quite different.
So, if you accidentally feed the wrong thing to the JSON.parse() method you will get an error. Note what happens when I give the JSON object to the JSON.parse() method:
console.log("Parse JSON:\n", JSON.parse(dataJSON))
/* result will be:
* Parse JSON:
* { key: 'value' }
*/
That is great! The JSON.parse() method is expecting a JSON string so it works properly.
But watch what happens then I try to feed JSON.parse() the JavaScript object we created:
console.log("Parse JS:\n", JSON.parse(dataJS))
/* result will be an ERROR:
* undefined:1
* [object Object]
* ^
*
* SyntaxError: Unexpected token o in JSON at position 1
*/
There's your error!
So, it means that what you're feeding your JSON.parse() method in your code is not a JSON string.
The "Unexpected token" error means that your JSON isn't formatted correctly. You can take a look at this site and put the contents of notes.json into it, and it will tell you whats wrong and what needs to be corrected

ServiceStack Deserializing Interface property null in object

I want to use ServiceStack JsonSerializer.
I am setting IncludeTypeInfo property true before I serialize my object.And my serialized string contains all type informations like "__type":".Interfacesb,....
When I want to deserialize string that time my interface property null even though I have type information in my serialized string.Is there any other configuration need when deserializing object.
I use two methods
JsonSerializer.SerializeToString and JsonSerializer.DeSerializeFromString
Example:
JsConfig.IncludeTypeInfo = true;
Public Class MyObject
{
Public string a{get;set;}
Public interface b{get;Set;}
}
First, the version 4.* is the continued developed version. 3.9 is not actively maintained by anyone.
Test on servicestack.text 4.50
Secondly i don't think this this property was made to de-serialize it back practical objects.
i did the same in 4.50 and it just doesn't deserialize:
Alternative solutions
Here you can read what to if you want the types from the json: https://stackoverflow.com/a/21603948/1275832.
When you have the type:
I use the following code as an alternative solution (note its an extension method) as a solution for run-time dynamic types (v4.50):
public static object FromJson(this string json, Type deserializeType)
{
return typeof(JsonSerializer).GetMethod("DeserializeFromString", BindingFlags.Static)
.MakeGenericMethod(deserializeType)
.Invoke(null, new[] { json });
}
and usage as: var object = (MyInterface)jsonString.FromJson(Type.GetType(AssemblyQualifiedNameString));

Enforcing type info on values of object arrays in ServiceStack

Is there a way to enforce the __type attribute when serializing object arrays as JSON? For example, I have following array:
var data = new object[]
{
"string value",
new Dictionary<string, object>
{
{"name", 1.23}
}
};
When I serialize this using
var json = JsonSerializer.SerializeToString(data);
I get following result
["string value",{"name":1.23}]
Deserializing using
var result = JsonSerializer.DeserializeFromString<object[]>(json);
// result == new object[] {"string value", "{name:1.23}"}
leads to an array containing two strings. The second one is the JSON serialized dictionary representation.
Is there a way to enforce the __type attribute to allow ServiceStack to deserialize to the right type? The array can contain almost anything JSON serializable.
This is an internal API with ServiceStack on both sides. The possible types are not known at compile time.

One time json serialization with type info in ServiceStack

We can set serialization settings via JsConfig in ServiceStack.
JsConfig.IncludeTypeInfo = true;
But we want to user Json serializing without "Type Info" except one place.
So how can we serialize with type info at there.
I think we need optional config parameter:
JsonSerializer.SerializeToString(x,**JsConfig**)
You can use a scope for only the place you need the type information:
using (JsConfig.With(new Config { IncludeTypeInfo = true }))
{
var json = new DTO().ToJson();
}

Resources