JSON deserialization error in WebApi with array - json

I'm posting the following JSON payload from a JavaScript Angular app to a webapi service:
{Notes: "test", Ids: [606, 603]}
this.http.post(url, {"Notes": "test", "Ids": [606,603]}, options)
I'm attempting to deserialize this into a .net Dictionary like:
[HttpPost]
public IHttpActionResult Test(Dictionary<string,string> formData)
{
}
(I've tried to add the [FromBody] decorator too).
If I don't include the array, this works fine. But with the array, I get a couple of parse error:
Unexpected character encountered while parsing value: [. Path 'Ids', line 1, position 23.
Invalid JavaScript property identifier character: ]. Path 'Ids', line 1, position 30.

The "JSON" you're posting is not valid JSON - you can use a tool like JSONLint to validate your JSON.
The correct JSON syntax for your data is:
{
"Notes": "test",
"Ids": [606, 603]
}
Also - the method takes a Dictionary<string,string> object. Your array is not a string, and the controller will therefore fail while trying to deserialize the array into a string.
My suggestion is to create a model, which the controller method should receive. Like this:
[HttpPost]
public IHttpActionResult Test(YourModel data)
{
}
class YourModel
{
public string Notes {get;set;}
public int[] Ids {get;set;}
}
Using this code, the controller will deserialize your JSON (when you have corrected the JSON syntax problems) into an instance of YourModel.

Related

KotlinX Serialization validate input bad json

Let's say I have a Request data class:
data class Request(
val firstName: String,
val lastName: String
)
which I want to serialize when getting to a specific api route. Using Ktor, it would look like this:
call.receive<Request>()
This would work perfectly if I get a valid json such as { "firstName: "TestFirst", "lastName": "TestLast" }
But, what if we get a json object or array instead of the expected string? { "firstName: [], "lastName": {} }?
The library would throw an exception and I wouldn't be able to know we had two different validation problems:
firstName must be a valid string (and not an array)
lastName must be a valid string (and not an object).
How can I find these errors so that I would be able to map them nicely back to the user in the rest api response?

How do I correctly deserialize json that consists of a list item that includes another object?

The client I am using returns json like this:
[
{
"source": "ANY"
}
]
That is, the element of the array that the object is in.
I'm trying to make a request like this:
restTemplate.postForObject<AbcdResponse>(
"/address",
listOf(value).let { JsonHttpEntity(it) }
)
data class AbcdResponse(
val obj: AbcdObject
)
data class DaDataAddress(
val source: String?
)
But I get the HttpMessageNotReadableException exception:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token
at [Source: (ByteArrayInputStream); line: 1, column: 1]
How can I deserialize the response correctly?
As you probably noticed, the response as a whole is a JSON array. You can tell by the square brackets [ ... ] surrounding the whole thing.
Because of this, you cannot deserialize it as an object (such as AbcdResponse). What you should do instead is use List<DaDataAddress> instead of AbcdResponse.
You don't really need AbcdResponse. What you need is to use a ParameterizedTypeReference as follows while calling the service:
restTemplate.exchange("/address",
HttpMethod.POST,
listOf(value).let { JsonHttpEntity(it) },
ParameterizedTypeReference<List<DaDataAddress>>() {})
The reason is that the service that you are calling is returning a JSON array of JSON objects.

How to convert ManagedCursorStreamProvider to JSOn object in mule 4

How to convert ManagedCursorStreamProvider to Json object in mule.
I have written a java method which takes the Json Object as input
Request Payload:
{ a: "one",
b : "two"}
Invoke static
arg0 : payload
Java Function called using invoke static
public static func(JsonObject json){
}
I am getting the following error:
Expected arguments are [com.google.gson.JsonObject jsonObject] and
invocation was attempted with arguments
[org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider
arg0].
No suitable transformation was found to match the expected type for
the parameter [jsonObject].
UPDATE:
I have updated my java method to accept String as input.
"Cannot coerce Object { encoding: UTF-8, mediaType: application/json; charset=UTF-8, mimeType: application/json, raw: org.mule.weave.v2.el.SeekableCursorStream#868075a } (org.mule.weave.v2.el.MuleTypedValue#7c0c5e89) to String
1| arg0 : vars.req as String
^^^^^^^^^^^^^^^^^^
Trace:
at main (line: 1, column: 8)" evaluating expression: "arg0 : vars.req as String".
Mule doesn't know how to convert to a GSON JsonObject. You can use DataWeave to transform it into a Java map. Alternatively, you can change the argument of the Java method to String and Mule will transparently convert the stream to a String. Be sure to use the latest version of the Java module.
If you want to convert to a custom type of object you will need to implement it yourself in Java.

Map of Instant to list of objects - jackson serialization/deserialization

I have a spring boot app and the following DTO class:
public class CarDto {
private Map<Instant, List<CarModelDto>> dateToCarModels = new HashMap<>();
// getters/setters omitted for brevity
}
When I make a call from postman it looks like this:
{
"dateToCarModels": {
"1544612555": [{
<obj1>
},
{
<obj2>
}],
"1544785355": [{
<obj1>
}]
}
}
It gives me the following error:
JSON parse error: Cannot deserialize Map key of type
`java.time.Instant` from String "1544612555": Failed to deserialize
java.time.Instant: (java.time.format.DateTimeParseException) Text
'1544612555' could not be parsed at index 0; nested exception is
com.fasterxml.jackson.databind.exc.InvalidFormatException: (...)
That is understandable as I have Instant as a key map (and pass String in json - since JSON keys must be strings).
Is there any better way to fix it than writting own key serializer/deserializer ?

How can my MVC controller produce JSON in the following format?

I'm trying to integrate jQuery validation engine with my MVC project to perform inline validation. I have a field inside a jQuery form which is calling to an MVC controller and expects a JSON response. According this article written by the plugin's author...
Now this will send the field in ajax to the defined url, and wait for
the response, the response need to be an array encoded in json
following this syntax: ["id1", boolean status].
So in php you would do this: echo json_encode($arrayToJs);
How to achieve this in ASP.NET MVC4?
My current controller looks like this.
public JsonResult FunctionName(string fieldValue)
{
return Json((new { foo = "bar", baz = "Blech" }), JsonRequestBehavior.AllowGet);
}
The response body shows that it returns key value pairs that look like this
{"foo":"bar","baz":"Blech"}
How can I return JSON in the expected format?
The square brackets indicate an array within a JSON object.
See this article: http://www.w3schools.com/json/json_syntax.asp
This test code:
return Json(new object[] { "id1", false }, JsonRequestBehavior.AllowGet);
should return:
["id1",false]
If you want to return an array within the json, which i think you do. Then you can return a Dictionary. Your not seeing an array in the json output now because of the anonymous type you are passing in is two key values.
public JsonResult MyMethodName(string name)
{
IDictionary<string, bool> myDict = LoadDictionaryFromSomewhere();
return Json(myDict, JsonRequestBehaviour.AllowGet);
}