How to parse this json with newtonsoft? - vb.net

{
"boxes": [
{
"hash": "51532859",
"owner": "9",
"id": "3868",
"isDisabled": false
"innerbox": {
"color": "aaaa",
"size": "bbbb"
}
},
{
"hash": "cccc",
"owner": "9",
"id": "3868",
"isDisabled": false
"innerbox": {
"color": "cccc",
"size": "dddd"
}
}
],
"meta": {
"currencies": {
"USD": {
"total": "2",
"value": "123456",
"currency": "USD",
"isDisabled": false
}
},
"total": 2
}
}
Above is the JSON (I've cut it down and replaced some info, but its the same format) that I retrieve from a web server. I am trying to use NewtonSoft JSON to Deserialize it but I am getting an error "because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly."
Here is my class:
Public Class TheBox
Public Property boxes() As Boxes
Public Property meta As Meta
Public Property usd As USD
Public Property innerbox As InnerBox
End Class
Public Class Meta
Public Property currencies As Currencies
Public Property total As Integer
End Class
Public Class Currencies
Public Property USD As USD
End Class
Public Class USD
Public Property total As String
Public Property value As String
Public Property currency As String
Public Property isDisabled As Boolean
End Class
Public Class Boxes
Public Property hash As String
Public Property owner As String
Public Property id As String
Public Property isDisabled As Boolean
End Class
Public Class InnerBox
Public Property color As String
Public Property size As String
End Class
This is how I am trying to Deserialize it:
Dim obj = JsonConvert.DeserializeObject(Of TheBox)(Json)
Any help is appreciated, thank you

Your current json as posted looks to be "bad" or malformed.
So, this:
"isDisabled": false
"innerbox": {
"color": "aaaa",
"size": "bbbb"
}
There is a comma (",") missing after the false.
so, it needs to be:
"isDisabled": false,
"innerbox": {
"color": "aaaa",
"size": "bbbb"
}
Same for the one further down.
Once you fix those two issues, then this json will and should parse just fine.
You can have Visual Studio create the classes for you like this:
Create a blank new class, and then ctrl-a and del key to empty out. Then this:
And now VS spits out this:
Public Class Rootobject
Public Property boxes() As Box
Public Property meta As Meta
End Class
Public Class Meta
Public Property currencies As Currencies
Public Property total As Integer
End Class
Public Class Currencies
Public Property USD As USD
End Class
Public Class USD
Public Property total As String
Public Property value As String
Public Property currency As String
Public Property isDisabled As Boolean
End Class
Public Class Box
Public Property hash As String
Public Property owner As String
Public Property id As String
Public Property isDisabled As Boolean
Public Property innerbox As Innerbox
End Class
Public Class Innerbox
Public Property color As String
Public Property size As String
End Class
So, the top most root item here is Root object - you can re-name that if you wish.
I not test above with the above data sample (first fix it), but I'm going for a coffee - if I have time, I will give your data a try with above code later.

Related

What is an efficient way to generate vb classes from json schemas?

Is there any way to generate vb classes from jsonschema files like we can generate classes from wsdls and xsds using wsdl.exe in one go.
I don't want to use Edit > Paste special > paste JSON as class feature of Visual Studio because I tried for one file and it did not give me the result I am expecting and also there are about 15 schema files so want a generic way.
On using Edit > Paste special > paste JSON as class feature of Visual Studio,
The schema have is:
{
"title": "MyObject",
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"id": {
"type": "string"
}
},
"required": [ "id", "description", "name" ]
}
The generated classes:
Public Class Rootobject
Public Property title As String
Public Property type As String
Public Property properties As Properties
Public Property required() As String
End Class
Public Class Properties
Public Property description As Description
Public Property name As Name
Public Property id As Id
End Class
Public Class Description
Public Property type As String
End Class
Public Class Name
Public Property type As String
End Class
Public Class Id
Public Property type As String
End Class

UnrecognizedPropertyException: Unrecognized field - jackson 2.9

I am doing a simple conversion using Jackson:
response = mapper.readValue(responseStr, PrinterStatus.class);
The code is throwing this exception:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "OutputParameters" (class com.xerox.PrinterStatus),
not marked as ignorable (one known property: "outputParameters"]) at ....
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
The Json I would like to convert is very simple:
{
"OutputParameters": {
"#xmlns": "http://xmlns.xerox.com/apps/rest/",
"#xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"GETPRINTERSTATUS": {
"GETPRINTERSTATUS_ITEM": [{
"STATUS": "True",
"MESSAGE": " "
}]
}
}
}
This is the PrinterStatus class, it has the field "OutputParameters"
So I am not sure what is Jackson yelling about.
public class PrinterStatus {
private OutputParameters outputParameters;
public OutputParameters getOutputParameters() {
return outputParameters;
}
public void setOutputParameters(OutputParameters outputParameters) {
this.outputParameters = outputParameters;
}
...
Basically JSON keys are case sensitive. Accordingly OutputParameters doesn't equal to outputParameters.
So you have to choose:
rename the field in Java class (and getters / setters too) to OutputParameters
rename JSON property key to outputParameters
If you using Jackson 2.9 or above just simply annotate field like this:
public class PrinterStatus {
#JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
private OutputParameters outputParameters;
public OutputParameters getOutputParameters() {
return outputParameters;
}
public void setOutputParameters(OutputParameters outputParameters) {
this.outputParameters = outputParameters;
}
...
}
Set property name explicitly
public class PrinterStatus {
#JsonProperty("OutputParameters")
private OutputParameters outputParameters;
...
}
Enable case insesitive feature globally
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

Cannot deserialize instance of MyEnum out of START_OBJECT token

Stuck with the problem of MyEnum enum deserialization from JSON to POJO and cannot figure out what I do wrong. So basically I try to retrieve some data calling particular microservice endpoint that returns the following json:
{
"id": "9cabf3e9-965d-4407-b62b-c57dd6006419",
"myEnums": [
{
"context": "SOME_FOO_CONTEXT_1",
"feature": "SOME_BAR_FEATURE_1",
"name": "SOME_FOO_BAR_1"
},
{
"context": "SOME_FOO_CONTEXT_2",
"feature": "SOME_BAR_FEATURE_2",
"name": "SOME_FOO_BAR_2"
}
],
"name": "Some name",
"updatedBy": null,
"updated": "2019-05-16T00:11:19.279Z"
}
This is the method that calls another microservice endpoint, deserialize response body to POJO and return result as Set:
private Mono<Set<MyEnum>> fetchMyEnums(UUID someId) {
return webClient.get().uri("/v1/something/{id}", someId)
.retrieve()
.bodyToMono(MyClass.class)
.flatMapIterable(MyClass::getMyEnums)
.collect(toSet());
}
The class that used for JSON deserialization:
#lombok.Value
static class MyClass {
List<MyEnum> myEnums;
}
Enum that I actually cannot deserialize:
#Getter
#RequiredArgsConstructor
#AllArgsConstructor
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {
SOME_FOO_BAR_1(SOME_FOO_CONTEXT_1, SOME_BAR_FEATURE_1),
SOME_FOO_BAR_2(SOME_FOO_CONTEXT_2, SOME_BAR_FEATURE_2);
private final FooEnum context;
private final BarEnum feature;
private String name;
#JsonProperty
public String getName() {
return super.name();
}
}
During deserialization I receive the following exception:
org.springframework.core.codec.DecodingException: JSON decoding error: Cannot deserialize instance of `com.learn.common.security.model.MyEnum` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.learn.common.security.model.MyEnum` out of START_OBJECT token
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.learn.common.security.service.MyEnumService$MyClass["myEnums"]->java.util.ArrayList[0])
Where I did mistake?
So spending few more hours to clarify what's the problem with deserialization i figure out that there is no automatic deserialization for Enum whose Shape.Object.
But I found workaround how to deserialize MyEnum object from json(you need define static method marked it as JsonCreator and define what input parameter you expect to catch from object defining JsonProperty with fieldName):
#Getter
#RequiredArgsConstructor
#AllArgsConstructor
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {
SOME_FOO_BAR_1(SOME_FOO_CONTEXT_1, SOME_BAR_FEATURE_1),
SOME_FOO_BAR_2(SOME_FOO_CONTEXT_2, SOME_BAR_FEATURE_2);
private final FooEnum context;
private final BarEnum feature;
private String name;
#JsonProperty
public String getName() {
return super.name();
}
#JsonCreator
public static MyEnum fromJson(#JsonProperty("name") String name) {
return valueOf(name);
}
}
For sake of completeness: You can add the #JsonCreator annotation either to a constructor or to a factory method.
Constructor:
#JsonCreator
public MyEnum(#JsonProperty("name") String name) {
this.name = name;
}
Factory method:
#JsonCreator
public static MyEnum fromJson(#JsonProperty("name") String name) {
return valueOf(name);
}
Multiple parameters:
If your enum type contains multiple properties, add them to the signature with #JsonProperty annotation.
#JsonCreator
public MyEnum(#JsonProperty("id") String id, #JsonProperty("name") String name) {
this.id = id;
this.name = name;
}
When using a factory method, creation from JSON might fail, if you have defined multiple properties. You may get this error message:
Unsuitable method [...] decorated with #JsonCreator (for Enum type [...])
Some versions of Jackson cannot handle this case. Use constructor method as a workaround, if your enum type contains more than one property.

How to get JacksonXML to de-serialize embedded objects

I am writing a REST interface using Jersey and have configured it to use JacksonXML to do the JSON<->POJO conversions. I have a set of classes like this:
#JsonInclude(JsonInclude.Include.NON_NULL)
public class JsonPo {
public Long id;
public String type;
public Boolean committed;
public String owner;
// ...
Which is referenced in my main class like this:
#JsonInclude(JsonInclude.Include.NON_NULL)
public class JsonPoReq {
public Long id;
public String pathstring;
public int firstrecord;
public JsonPo obj;
// ...
And the REST resource of course looks like this:
#POST
#Path("path")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response byPath(JsonPoReq req) {
// ...
The serialization (POJO->JSON) works fine. The properties in the JsonPo object get serialized in a JSON object as you would expect.
The reverse doesn't work. Even if I feed the serialized string back. What happens is the obj property is always set to null.
EDIT: As requested the following is what the JSON string looks like:
{
"id" : 2,
"pathstring" : "/a/b/c",
"firstrecord" : 0,
"obj" : {
"id" : 2,
"type" : "ProtoObject",
"committed" : false,
"owner" : "admin"
}
}
I have been going through the JacksonXML Annotations to see how to fix this but I haven't been able to come up with anything. Is there some other step I am supposed to take?
UPDATE: Problem was not real. Some application code was being invoked that I didn't notice was clearing the object.

Read DropBox info.json file with .NetJSON

Any ideas, I don't understand the Object I need to define. I am coding in VB but C# is OK. The file is one line but seems to have some nesting with Personal and Business.
{
"personal": {
"path": "C:\\Users\\Paul\\Dropbox (Personal)",
"host": 4897400149,
"is_team": false,
"subscription_type": "Basic"
},
"business": {
"path": "C:\\Users\\Paul\\Dropbox (Y2016)",
"host": 4897401185,
"is_team": true,
"subscription_type": "Business"
}
}
You can define your classes as follows:
Public Class DropBoxFolderPath
Public Property path As String
Public Property host As Long
Public Property is_team As Boolean
Public Property subscription_type As String
End Class
Public Class DropBoxFolderPaths
Public Property personal As DropBoxFolderPath
Public Property business As DropBoxFolderPath
End Class
Then deserialize as follows:
Dim dropBoxFolders = JsonConvert.DeserializeObject(Of DropBoxFolderPaths)(jsonString)
Example fiddle. Related documentation: How can I programmatically find the Dropbox folder paths?.