When I call a PageMethod in my page, the serialized object looks like:
{"d":{"__type":"MyAsembly.MyNamespace.Person","Name":"ulu","Age":40}}
This is ok for Javascript, but my .Net deserializer won't understand it:
var result= new JavaScriptSerializer(new SimpleTypeResolver()).Deserialize<Person>(source);
throws System.InvalidOperationException: Operation is not valid due to the current state of the object.
Now, the actual problem is that the Activator can't create the result object: it doesn't understand "MyAsembly.MyNamespace.Person" and needs "MyAsembly.MyNamespace.Person, MyAssembly".
The question is, what do I need to change so that serialization becomes compatible with deserialization?
Thanks a lot
ulu
Seems like you already know the answer: modify the value of the __type property before serializing the object on the JavaScript side. Alternatively, you could do a replace on the serialized data before pushing it through the deserializer.
Question though: where is the data being serialized? If you're doing it in .NET and then sending it to the client, it shouldn't need any modification when it gets back to the server unless something tampered with the __type property.
I am guessing that
{"d":{"__type":"MyAsembly.MyNamespace.Person","Name":"ulu","Age":40}}
should be
{"d":{"__type":"MyAssembly.MyNamespace.Person","Name":"ulu","Age":40}}
Related
I reported this issue https://github.com/dotnet/runtime/issues/48816 and the developer that responded posted code explaining how to manually deserialize the function argument. Asp is supposed to have an automated system for this however. So if my function definition looks like:
[Authorize]
[HttpPost]
public async Task<IActionResult> Post(Session session)
{
...
then I am supposed to be able to just use session as a variable from that point without any special deserialization step. This suggests to me that there must be a way to set JsonSerializerOptions(JsonSerializerDefaults.Web) somewhere in a more global way so that it can consume the post data it is getting. Alternatively there might be a different way to serialize the post data differently on the client so that it does not get converted to camel case.
The main question is: what is the correct way to serialize and deserialize data objects for asp.net-core?
To Reproduce
Thanks for Roar S's comment, use [FromBody], it works.
I have a java application that outputs data in Json format (via Gson). I write that data to a file. That file is then read by a C++ application. The C++ application is using jsoncpp to deserialize the json. However, it appears that the C++ application cannot properly deserialize the Json (which is the whole point of using Json).
The problem seems to relate to the class name being included in the Gson output. Gson output sample:
{"nameOfClass":{"fieldName":"fieldvalue","secondFieldName":1}
As far as I can tell, "nameOfClass" is throwing off jsoncpp. Perhaps my jsoncpp deserialize method is incorrect? I have specific code to handle the different fields, but nothing that specifically handles that initial class name. Is that something I need to handle?
Short answer: user error
Longer answer:
It turns out I was serializing the wrong object. The class of this object CONTAINS a field of type "nameOfClass". What I wanted was that FIELD to be serialized, not the whole object. Because of my inexperience with Json and unfortunate choice of the field's name, I thought the output was malformed. Once I got the field from the object and serialized that, everything was fine.
I am trying to send information about an error event using ipcRenderer.send("error", errorObject) but my Error object gets serialized to '{}' in the listener. Now, I know that ipcRenderer serializes objects to JSON internally (More information here: https://electronjs.org/docs/api/ipc-renderer) so I want to find out what method is called for serialization to JSON internally so that I can try to override it in my code. Can anyone help?
I guess it's using JSON.stringify() but it's probably serialized for security reason so maybe it's better to not override it. BTW I don't think override JSON.stringify() is a good practice in any way. I didn't notice ipcRenderer.send serialized data, I pass plain JavaScript Object as data and don't parse it on ipcMain side.
I am attempting to consume an API that I do not have control over which is somewhat poorly documentented and somewhat inconsistent. This means that sometimes, the API returns a different type than what is documented or what you would normally see. For this example, we'll look at a case when an array was returned in a place where I would normally see a string. That makes a crappy API, but my real problem is: How can I more easily track those things down? Right now, the errors look something like this:
No usable value for identifier
Do not know how to convert JArray(List(JString(3c8723eceb1a), JString(cba8849e7a2f))) into class java.lang.String
After deciphering the problem (why JValue::toString doesn't emit a JSON string is utterly perplexing to me), I can figure out the API returned an array when I made my case class only able to deal with Strings. Great. My issue is that finding this discrepancy between my object model and the contents of the JSON seems significantly more difficult than it should be.
Currently, this is my workflow for hunting down decoding errors:
Hope bad data has some sort of identifying marker. If this is not true, then it is way more guesswork and you will have to repeat the following steps for each entry that looks like the bad bits.
Go through the troubles of converting the JArray(List(JString(...), ...)) from the error message into valid JSON, hoping that I encode JSON the same way at the API endpoint I got the data from does. If this is not true, then I use a JSON formatter (jq) to format all data consistently.
Locate the place in the source data where the decoding error originates from.
Backtrack through arrays and objects to discover how I need to change my object model to more accurately represent what data is coming back to me from the API.
Some background: I'm coming from C++, where I rolled my own JSON deserialization framework for this purpose. The equivalent error when using the library I built is:
Error decoding value at result.taskInstances[914].subtasks[5].identifier: expected std::string but found array value (["3c8723eceb1a","cba8849e7a2f"]) at 1:4084564
This is my process when using my hand-rolled library:
Look at the expected type (std::string) compared with the data that was actually found (["3c8723eceb1a","cba8849e7a2f"]) and alter my data model for the path for the data in the source (result.taskInstances[914].subtasks[5].identifier)
As you can see, I get to jump immediately to the problem that I actually have.
My question is: Is there a way to more quickly debug inconsistencies between my data model and the results I'm getting back from the API?
I'm using json4s-native_2.10 version 3.2.8.
A simplified example:
{ "property": ["3c8723eceb1a", "cba8849e7a2f"] }
Does not mesh with Scala class:
case class Thing(property: String)
The best solution would be to use Try http://www.scala-lang.org/api/current/#scala.util.Try in Scala, but unfortunately json4s API cannot.
So, I think you should use Scala Option type http://www.scala-lang.org/api/current/#scala.Option .
In Scala, and more generally in functional languages, Options are used to represent an object that can be there or not (like à nil value).
For handle parsing failures, you can use parse(str).toOption, which is a function that return an Option[JValue], and you can doing a pattern matching on the resulting value.
For handling extraction of data extraction into case classes, you can use extractOpt function, to do pattern matching on the value.
You can read this answer : https://stackoverflow.com/a/15944506/2330361
I am currently using the this Jackson plugin
Which serialized my cyclical graphs. Then on the client I use the JSOG to decode the {#ref} objects like this:
JSOG.decode(data)
The problem comes when I am trying to send the json back up to the server. If I don't do anything to the data I get a "Maximum call stack size exceeded", obviously because my js object is cyclical. I try using:
JSOG.stringify(data);
But then Jackson chokes on all the #id and #refs:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "#id"
Has any one figured out how to do this?
Both sides need to be able to support JSOG convention. It is not part of JSON specification, nor can it be automatically detected; so Jackson can not process it without help.