Does the business logic for deserializing a JsonPayload have to match? - json

I am currently attempting to deserialize a Json Payload that has been fired from a webhook URL on an MVC application, but I do not know if the business logic provided has to match exactly to prevent any null values.
Basically the Json Payload contains way to much useless information that I do not what to display. This is a brief preview of what the Payload looks like:
"webhookEvent":"jira:issue_updated",
"user":{
"self":"http://gtlserver1:8080/rest/api/2/user?username=codonoghue",
"name":"codonoghue",
"issue":{
"id":"41948",
"self":"http://gtlserver1:8080/rest/api/2/issue/41948",
"key":"OP-155",
"fields":{
"summary":"Test cc recipient",
"progress":{
"progress":0,
"total":0}, ....
I only want to display information about the issue and the other information is just white noise to me and don't want to use it. Now do I have to create classes only for the issue details etc like this:
Public Class jiraIssue
Public Property id As String
Public Property key As String
Public Property fields As jiraFields
End Class
Or do I have to make sure to provide sufficient business logic about the User class just to make sure that it will be received correctly? I also know that using Json2csharp.com the classes that can be made are user, issue, fields, progress as well as the overall RootObject, so I also want to know is do these classes need to contain the exact same matching variables as the JsonPayload, e.g. I don't want progress to have the variable total.
When using Json2csharp that in every class they contain an ID variable with the property as string and I would like to know if this is needed in the classes to be able to display the information or can I not use it as it is also irrelevant.
The main thing that I want to deserialize is the RootObject, which contains a webhookEvent (string) an issue (which links to issue class, which links to fields class which links to all relevant information), comment which links to a comment class. I want to deserialize this so would this be correct?
Public Class Rootobject
Public Property webhookEvent As String
Public Property issue As Issue
Public Property comment As Comment2
Public Property timestamp As Long
End Class
Public Class Issue
Public Property key As String
Public Property fields As Fields
End Class
Public Class Fields
Public Property issueType as IssueType
Public Property summary As String
Public Property summary As String
End Class
Dim Issue As RootObject = New System.Web.Script.Serialization.JavaScriptSerializer().Deserialize(Of RootObject)(json)
For Each item As var In Issue.issue
Console.WriteLine("WebhookEvent: {0}, issue: {1}", item.WebhookEvent, item.issue)
Next
Update
It seems that the problems that I was having was due to the JsonPayload itself, the business logic did not affect. There were issues with the incompatible characters, some fields were null and could not be and a few others as well.

I have correctly got my Json payload correctly read in and the Json Payload information does not have to correctly match up with the classes that you create. You only have to create classes and variables for the information that you need from the Json Payload. For example if you did not want the information on comments do not create a comment class.
Public Class Rootobject
Public Property webhookEvent As String
Public Property issue As Issue
' Public Property comment As Comment2
' comment out the comment class because it is not needed
Public Property timestamp As Long
End Class

Related

Add and remove data from object class

I'm just learning how to work with Json files and my goals are:
Be able to read a Json file
View the info on a TreeView
Be able to Modify, Add, and remove items
Make again the Json File.
For doing this i've learned about Newtonsoft.Json, that helps a lot. I've almost achieved all my goals except being able to add and remove items from my object.
First of all, I load all the Json content to:
Dim ImportedTeams as Teams()
The code for the class objects are the following:
Public Class Teams
Property drivers As Drivers()
Property raceNumber As String
Property CarModel As String
Property ballastKg As String
Property restrictor As String
End Class
Public Class Drivers
Property firstName As String
Property lastName As String
End Class
I have the ImportedTeams with all data filled, from there I get all I need to fill the Treeview, with diferents levels of nodes, etc. Also, I can modify the info stored in the class, and make the Json again. No problems until this point
My problems starts here, when I want to add a new Team. What I tried is the following:
Dim NewTeam As New Teams
Dim NewDriver as New Drivers
With NewDriver
.firstName = TB_Name.text
.lastName = TB_LastName.text
End With
With NewTeam
.drivers = NewDriver()
.raceNumber = NUD_RaceNumbre.Value.ToString
.CarModel = CBB_Car.index
.ballastKg = TB_Ballast.Text
.restrictor = TB_Restrictor.Text
End With
ImportedTeams.append(NewTeam)
This simply wont work. Don't shows up any error, just nothing happens. Also, I don't know how to remove one Team stored in this object.
I also tried to add only a NewTeam, but same problem.
Thanks for your time mates, any help would be appreciated.
As Alex B. said, the solution is easy as follows:
Public Class Teams
Property drivers As **List(of Drivers)**
Property raceNumber As String
Property CarModel As String
Property ballastKg As String
Property restrictor As String
End Class
Public Class Drivers
Property firstName As String
Property lastName As String
End Class
And:
Dim ImportedTeams as **List(of Teams)**
Thanks!

GSON not reading values correctly

I'm trying to read this JSON:
And I can't seem to get it to work with GSON. I've used GSON successfully in the same project so I know how it works but I can't seem to get this JSON to work as intended. First in the class is rows, which is just an array of another class. The other class has three variables, a string named "code", a string named "name", and a array of another class called "statuses". However, I don't know how to put variables in this other class. It looks like an array but it's not. I cannot name a variable "0" in Java, so I looked that up (tried fixing it with Maps) but that did not work. How would you do this? It's weird because "statuses" always contains just that one entry, named '0', and the text is either "primary" or "secondary". Any help is appreciated.
I actually found this:
Still not really sure how to go about this.
Your Pojo design shoild be like this :-
public class ResultOutPut {
private List<Rows> rows;
// getters and setters
}
public class Rows {
private String code;
private String name;
private List<String> statuses;
// getters and setters
}

Access deserialized object from custom deserializer

All classes in my model are subclasses of a common base-class Node.
When serializing/deserializing with Jackson, I want references to other objects to be replaced by their ID. The problem is, that the ID is a combination of two values: the ID of the instance itself, and the ID of a source. I do this with a custom serializer and deserializer.
Serializing is no problem. I write JSON with a structure like this:
{"id":1,"source":2,"name":"Some record","reference":3}
But when deserilizing, I need to know the ID of the source and the ID of the referenced node, to be able to look it up in my custom deserializer.
Is it possible, to access the values of the deserialized instance, to get access to the ID of the source when deserializing the reference?
Here is what I tried so far:
public class MyDeserializer extends JsonDeserializer<Node>
{
#Override
public NodeData deserialize(...)
{
Node parent = (Node)parser.getCurrentValue();
Long id = parent.getId();
Long id = parser.getLongValue();
return NodeDataService.INSTANCE.get(source, id);
}
}
But parser.getCurrentValue() always returns a null.
My best solution so far is, to write a cooperation pair of deserializers.
The first one is annotated to the getter of the attribute source and stores
the value as per-call attribute. The second looks like this:
public class MyDeserializer extends JsonDeserializer<Node>
{
#Override
public NodeData deserialize(...)
{
Long source (Long)context.getAttribute("SOURCE");
Long id = parser.getLongValue();
return NodeDataService.INSTANCE.get(source, id);
}
}
This works, but I am asking myself, if there is an easier way to achieve this.
This question looks like it is possible, like I did it in my first attempt - but only while serializing:
Jackson How to retrieve parent bean in a custom Serializer/Deserializer
getCurrentValue() will return null as you've entered into a new JSON object but not yet set the current value. You need to look at the stack of deserialized values in the parser context.
I answered something similar here, which is the deserialization equivalent of the serialization question you linked to: Jackson JSON gives exception on collection of nested class
In summary you can get the stream context:
JsonStreamContext ourContext = p.getParsingContext();
and then repeatedly call getParent() on contexts to walk up the chain, calling getCurrentValue(). The value is set into the stream context as soon as the standard bean deserializer constructs the object.

How do you deserialize this JSON object into a vb.net object?

I'm using JSon.net to deserialize a json object i'm getting from the GravityForms Web API.
The json that I get back is this...
{"status":200,"response":{
"12":{"id":"12","title":"Test Form","entries":"1"},
"1":{"id":"1","title":"What's My Home Worth?","entries":"92"}
}
}
My VB.net Object that I'm deserializing into is
Namespace Forms
Public Class GFForm
Public Property id As String
Public Property title As String
Public Property entries As String
End Class
Public Class Response
<JsonProperty("1")>
Public Property GFForms() As GFForm
End Class
Public Class TopLevel
Public Property status As Integer
Public Property response As Response
End Class
End Namespace
and I am executing the JsonConvert statement like this..
Dim obj As GravityForms.Forms.TopLevel
obj = JsonConvert.DeserializeObject(Of GravityForms.Forms.TopLevel)(str)
It seems to successfully deserialize the json into my vb object but I am only getting 1 response object. I should be getting 2 of them right?
The odd thing is that the GFForm that I'm getting is the second one (ID:1), which makes it seem like it's over writing the value of the first object (ID:12).
Any help would be great because I've been messing with this for the better part of 2 days and I'm lost.
Edit:
This was not clear in my question above. I do not know the number of GFForm objects that I get back from the web service. It could be 2 (like in the example) or it could be 32 or 45 or whatever.
I'd like to put the GFForm objects in something I can bind to a datagridview
You have two GFForm properties in your response, but one Response object with one property to fill. Maybe you should try using something like that
Namespace Forms
Public Class GFForm
Public Property id As String
Public Property title As String
Public Property entries As String
End Class
Public Class Response
<JsonProperty("1")>
Public Property GFForms1 As GFForm
Public Property GFForms12 As GFForm
End Class
Public Class TopLevel
Public Property status As Integer
Public Property response As Response
End Class
End Namespace
EDIT: If you don't know the number of response properties, try creating a new Response object for each property.

Mapping a field name beginning with an underscore in Entity Framework 4.1 Code First

I have a class that contains a few private/protected fields and some public getters that return the value of the fields. I am attempting to map the fields to database columns using the fluent API on the DbModelBinder in OnModelCreating. I cannot use an automatic property with a protected setter so please don't offer that as a solution to my question. It would probably work I'm sure but I cannot use the automatic property as the domain class is shared code and used with other different ORMs that have different ways of mapping their fields and unfortunately one doesn't support the au
I use the following code (found on stackoverflow) to access the protected field so that I can use the expression when mapping:
public static class ObjectAccessor<T>
where T : class
{
public static Expression<Func<T, TResult>> CreateExpression<TResult>(string propertyOrFieldName)
{
ParameterExpression param = Expression.Parameter(typeof(T), "propertyOrFieldContainer");
Expression body = Expression.PropertyOrField(param, propertyOrFieldName);
LambdaExpression lambda = Expression.Lambda(typeof(Func<T, TResult>), body, param);
return (Expression<Func<T, TResult>>)lambda;
}
}
This all works wonderfully if the field name is m_username but if I use _username I get a ModelValidationException: One or more validation errors were detected during model generation: System.Data.Edm.EdmProperty: Name: The specified name is not allowed: '_username'.
I can't use camelcase without the underscore either as the helper above can't distinguish between the public Username property and the protected username field. I'd really like to still keep using the underscore camelcase without the letter prefix.
Is it possible to configure the ModelBinder in some way so that the validation accepts the property name with a leading underscore?
Thanks in advance,
Mark
It seems that decoration of your field like this :
[Column("username")]
public string _username
maybe helpful in your case, anyway - please review similar case