Optional ApiModelProperty appearing in JSON Swagger response with null value - json

I am having trouble modifying a model class used by Swagger.
I would like to add new optional properties within a service response.
So I did modify my class like this :
#ApiModelProperty(required=false,value="This field is optional in response")
public String myNewProp;
Whenever I test my generated code, this field does appear in the response body even when it should not with null value :
{ "newProp": null }
Am I misunderstanding the "required=false" option ?
What did I miss ?

Solved, I just had to add this Jackson annotation for the given field :
#JsonInclude(JsonInclude.Include.NON_NULL)
#ApiModelProperty(required=false,value="This field is optional in response")
public String myNewProp;

Related

Is there any JSON filter to restrict undefined properties that are passed in HTTP request in Spring REST API

{
"id":100,
"name":"Ram",
"flag" : FALSE,
"dept" :"Software"
}
Above is my JSON input format for one of my Spring 4.x REST API. Following is my DTO.
public class EmployeeDTO {
private long id;
private String name;
private Boolean flag;
private String dept;
//getXXX & setXXX
}
If I am passing any extra parameters like below, additional parameters are ignored by the application (by default, please correct if my assumption is wrong).
{
"id":100,
"name":"Ram",
"flag" : FALSE,
"dept" :"Software"
"extra1":"unwanted",
"extra2" :"This also unwanted"
}
But, I do not want any extra fields to be in the input format, rather I want to restrict only DTO variables to be included in the input JSON. Can anyone help me in this.
Thanks in advance.

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

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

Why is my Web API controller action not deserializing child properties of child properties?

I'm sending a json payload in a PUT request to a web API controller action. The action in question has a signature that looks like this:
public IHttpActionResult Post([FromBody]SaveThingRequest request)
SaveThingRequest looks something like this:
public class SaveThingRequest
{
public List<ElementInfo> Elements { get; set; }
public class ElementInfo
{
public List<ElementSettingInfo> Settings { get; set; }
public class ElementSettingInfo
{
public string Name { get; set; }
public string Value { get; set; }
}
}
}
I'm posting json in the body of the request that contains Elements that have Settings. I've confirmed this by manually deserializing in the controller action and confirming that the JSON has a structure that looks something like:
{
Elements: [
{
Settings: [
{
Name: 'Name 1',
Value: 'Value 1'
},
{
Name: 'Name 2',
Value: 'Value 2'
}
]
},
{
Settings: [
{
Name: 'Name 1',
Value: 'Value 1'
},
{
Name: 'Name 2',
Value: 'Value 2'
}
]
}
]
}
However, when .NET deserializes the payload and creates the SaveThingRequest, my Elements are populated but all of them have a null Settings property. I don't know how else to troubleshoot this. Does anyone have any thoughts on what might be going on here?
This question should be deleted. It works as advertised. My problem was that I had an additional property on the JSON called 'settings' (lower-case) that the deserializer was trying to match because NewtonSoft deserialization attempts a non-case sensitive match if a case sensitive one isn't found. I was able to discover what was happening by changing the signiture of the method to:
public IHttpActionResult Post([FromBody]string request)
and then adding this to the method implementation:
var result = JsonConvert.DeserializeObject<SaveThingRequest>(request);
I got a deserialization exception saying:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[Noteable.Contracts.ClinicalReports.SaveThingRequest+ElementInfo+ElementSettingInfo]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly. To fix this error either change the JSON to a JSON array
(e.g. [1,2,3]) or change the deserialized type so that it is a normal
.NET type (e.g. not a primitive type like integer, not a collection
type like an array or List) that can be deserialized from a JSON
object. JsonObjectAttribute can also be added to the type to force it
to deserialize from a JSON object. Path
'Elements[0].settings.TextSize', line 11, position 20.
The end of the message showed me what was being deserialized when the deserializer failed and pointed me in the right direction. =[
I was stuck in the same problem. However, the problem was something else.
In my case, the property that was not getting serialize was declared without public access specifier. I declared it to public, and it ran perfectly fine.
Hope this will help someone who got stuck in this situation. It took me 20 mins to reach this solution.
Make sure you didn't do something stupid like I did and sent a partially 'stringified' JSON string from the browser instead of a JSON object.
See the problem? I didn't at first until I tried deserializing it from a string and then I realized that shippingAddress itself was a string instead of being an actual JSON object. The rest of the object was proper JSON, but I accidentally serialized the shippingAddress field.
{
"fspID": 571285,
"foo": 444,
"shippingAddress": "{\"countryCode\":\"US\",\"firstName\":\"Test User\",\"lastName\":null,\"address1\":\"1 Main St4\",\"address2\":null,\"company\":null,\"city\":\"San Jose\",\"stateOrProvince\":\"California\",\"stateCd\":\"CA\",\"zipOrPostal\":\"95131\",\"countryName\":\"United States\",\"countryDesc\":\"United States\",\"phone\":null,\"phone2\":null}"
}
If you are using JSON.NET and the attribute [JsonProperty] to name a property – make sure you haven't accidentally copy pasted the same property twice and forgotten to update the string value.
[JsonProperty("billingAddress")]
public Address BillingAddress { get;set; }
[JsonProperty("billingAddress")]
public Address ShippingAddress { get;set; }
This will throw a Newtonsoft.Json.JsonSerializationException that won't actually be visible to you and will screw up the model.
I had the same problem that the child property was null. However the problem was something else.
I had only a getter on the property, once I added a setter as well, then the property was set as expected.

Controller action enum parameter binding as string

I have a Web API controller action
[Route("{type}")]
public IEnumerable<Content> Get(ContentType type)
{
...
}
where ContentType is enumeration and type is being provided as a string and not as an integer.
As I've checked the JsonConverterAttribute class which seems it should be possible to put it beside a method parameter
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Struct |
AttributeTargets.Enum |
AttributeTargets.Property |
AttributeTargets.Field |
AttributeTargets.Interface |
AttributeTargets.Parameter, // <= HERE!
AllowMultiple = false)]
public class JsonConverterAttribute : Attribute
...
but this doesn't seem to work:
[Route("{type}")]
public IEnumerable<Content> Get([JsonConverter(typeof(StringEnumConverter))] ContentType type)
{
...
}
I'm getting an error:
The parameters dictionary contains a null entry for parameter 'type' of non-nullable type '....ContentType' for method '...' in '...'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
I also don't want to put this converter inside my global configuration as I want my enums to serialize as integers. There are just a few places where I need to deserialize them from strings.
The possible alternative is to pass in a string and parse it manually using Enum.Parse() method but I'd like to avoid it if possible.

Is . char allowed in JSON field name?

Is . char allowed in JSON field name?
java.lang.IllegalArgumentException: instance.id is not a valid JSON field name.
at com.google.gson.JsonFieldNameValidator.validate(JsonFieldNameValidator.java:52)
Atleast gson library seems to be complaining. But I couldn't find anything in json spec.
Note that I have serialized name annotation to avoid issue in java field name.
#SerializedName("instance.id")
private String instanceId;
Update:
It is a bug in serializedname and This is the fix I did:
#SdeSerializedName("instance.id")
private String instanceId;
and
new GsonBuilder().setFieldNamingStrategy
(new FieldNamingStrategy() {
public String translateName(final Field field) {
final SdeSerializedName annotation = field.getAnnotation(SdeSerializedName.class);
return ((null != annotation) && null != annotation.value()) ? annotation.value() : field.getName();
}
})
It is allowed in JSON itself, but (if I understand the GSON documentation correctly) the error message is because it can't map instance.id to a Java class member of the same name.
Have a look at Following thread about a similar problem mapping field names:
http://groups.google.com/group/google-gson/tree/browse_frm/month/2010-05/e575bb65cdd30410?rnum=31&_done=/group/google-gson/browse_frm/month/2010-05?&pli=1
Since the dot "." is already the separator between an object and a member name in javascript (this is where json originates), it cannot be a valid field name.