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

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);
}

Related

JSON deserialization error in WebApi with array

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.

Web API JSON string result contains double quotes around value for dynamic object

My controller is as follows...
public IHttpActionResult GetData()
{
IEnumerable<dynamic> result = api.getData();
string json = JsonConvert.SerializeObject(result);
return Ok(json);
}
returns raw text from fiddler
{"#odata.context":"https://localhost:44305/api/$metadata#Edm.String","value":"[\r\n {\r\n \"UserName\": \"test#gmail.com\"\r\n }\r\n]"
You notice the JSON object for value has double quotes around it and the special characters \r\n. How do I get it to return pure JSON format???
I am not getting more details from your code but have you tried this way.
Is there any specific reason to use a serialized object?
[System.Web.Http.HttpGet]
public IEnumerable<XYZ> GetData()
{
return api.GetData();
}
Hope this helps!!!
It's by design since you are returning a json string..
Do this in js: JSON.parse(response.data)

Grails: Easy and efficient way to parse JSON from a Request

Please pardon me if this is a repeat question. I have been through some of the questions/answers with a similar requirement but somehow got a bit overwhelmed and confused at the same time. My requirement is:
I get a JSON string/object as a request parameter. ( eg: params.timesheetJSON )
I then have to parse/iterate through it.
Here is the JSON that my grails controller will be receiving:
{
"loginName":"user1",
"timesheetList":
[
{
"periodBegin":"2014/10/12",
"periodEnd":"2014/10/18",
"timesheetRows":[
{
"task":"Cleaning",
"description":"cleaning description",
"paycode":"payCode1"
},
{
"task":"painting",
"activityDescription":"painting description",
"paycode":"payCode2"
}
]
}
],
"overallStatus":"SUCCESS"
}
Questions:
How can I retrieve the whole JSON string from the request? Does request.JSON be fine here? If so, will request.JSON.timesheetJSON yield me the actual JSON that I want as a JSONObject?
What is the best way to parse through the JSON object that I got from the request? Is it grails.converters.JSON? Or is there any other easy way of parsing through? Like some API which will return the JSON as a collection of objects by automatically taking care of parsing. Or is programatically parsing through the JSON object the only way?
Like I said, please pardon me if the question is sounding vague. Any good references JSON parsing with grails might also be helpful here.
Edit: There's a change in the way I get the JSON string now. I get the JSON string as a request paramter.
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON) // No problem here. Returns a JSONObject. I checked the class type.
def jsonArray = jsonArray.timesheetList // No problem here. Returns a JSONArray. I checked the class type.
println "*** Size of jsonArray1: " + jsonArray1.size() // Returns size 1. It seemed fine as the above JSON string had only one timesheet in timesheetList
def object1 = jsonArray[1] // This throws the JSONException, JSONArray[1] not found. I tried jsonArray.getJSONObject(1) and that throws the same exception.
Basically, I am looking to seamlessly iterate through the JSON string now.
I have wrote some code that explains how this can be done, that you can see below, but to be clear, first the answers to your questions:
Your JSON String as you wrote above will be the contents of your POST payload to the rest controller. Grails will use its data binding mechanism to bind the incomming data to a Command object that your should prepare. It has to have fields corresponding to the parameters in your JSON String (see below). After you bind your command object to your actual domain object, you can get all the data you want, by simply operating on fields and lists
The way to parse thru the JSON object is shown in my example below. The incomming request is esentially a nested map, with can be simply accessed with a dot
Now some code that illustrates how to do it.
In your controller create a method that accepts "YourCommand" object as input parameter:
def yourRestServiceMethod (YourCommand comm){
YourClass yourClass = new YourClass()
comm.bindTo(yourClass)
// do something with yourClass
// println yourClass.timeSheetList
}
The command looks like this:
class YourCommand {
String loginName
List<Map> timesheetList = []
String overallStatus
void bindTo(YourClass yourClass){
yourClass.loginName=loginName
yourClass.overallStatus=overallStatus
timesheetList.each { sheet ->
TimeSheet timeSheet = new TimeSheet()
timeSheet.periodBegin = sheet.periodBegin
timeSheet.periodEnd = sheet.periodEnd
sheet.timesheetRows.each { row ->
TimeSheetRow timeSheetRow = new TimeSheetRow()
timeSheetRow.task = row.task
timeSheetRow.description = row.description
timeSheetRow.paycode = row.paycode
timeSheet.timesheetRows.add(timeSheetRow)
}
yourClass.timeSheetList.add(timeSheet)
}
}
}
Its "bindTo" method is the key piece of logic that understands how to get parameters from the incomming request and map it to a regular object. That object is of type "YourClass" and it looks like this:
class YourClass {
String loginName
Collection<TimeSheet> timeSheetList = []
String overallStatus
}
all other classes that are part of that class:
class TimeSheet {
String periodBegin
String periodEnd
Collection<TimeSheetRow> timesheetRows = []
}
and the last one:
class TimeSheetRow {
String task
String description
String paycode
}
Hope this example is clear enough for you and answers your question
Edit: Extending the answer according to the new requirements
Looking at your new code, I see that you probably did some typos when writting that post
def jsonArray = jsonArray.timesheetList
should be:
def jsonArray = jsonObject.timesheetList
but you obviously have it properly in your code since otherwise it would not work, then the same with that line with "println":
jsonArray1.size()
shuold be:
jsonArray.size()
and the essential fix:
def object1 = jsonArray[1]
shuold be
def object1 = jsonArray[0]
your array is of size==1, the indexing starts with 0. // Can it be that easy? ;)
Then "object1" is again a JSONObject, so you can access the fields with a "." or as a map, for example like this:
object1.get('periodEnd')
I see your example contains errors, which lead you to implement more complex JSON parsing solutions.
I rewrite your sample to the working version. (At least now for Grails 3.x)
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON)
println jsonObject.timesheetList // output timesheetList structure
println jsonObject.timesheetList[0].timesheetRows[1] // output second element of timesheetRows array: [paycode:payCode2, task:painting, activityDescription:painting description]

ContentType application/json in ASP.NET WebAPI

I'm building my first WebAPI using ASP.NET MVC 4 WebAPI.
The requests must be sent using the application/json ContentType with utf-8 as the character set.
My POST method looks like this:
public HttpResponseMessage Post([FromBody]string value)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
Whenever I'm sending a POST request the parameter 'value' is null. The request body contains Json: { "name":"test" }.
What I prefer is to have the parameter of the Post method to be either a string containing the Json or be of type JObject (from the JSON.NET library). How do I accomplish this? And is this even possible?
The easiest way is to grab the raw string directly from Request.Content:
public async Task<HttpResponseMessage> Post()
{
string value = await Request.Content.ReadAsStringAsync();
return new HttpResponseMessage(HttpStatusCode.OK);
}
There is a way to make ASP.NET Web Api treat your request body as string content, but in order to do that the content must be in =value format, in your case something like this:
={ "name":"test" }
You can achieve something like this with following jQuery code (for example):
$.post('api/values', '=' + JSON.stringify({ name: 'test' }));
In that case you can use signature from your question.
In the end there is always an option of creating your own MediaTypeFormatter to replace the default JsonMediaTypeFormatter and make it always deserialize the content into JObject. You can read more about creating and registering MediaTypeFormatter here and here.

Is there a way to add an additional field to Grails JSON response?

I want every JSON response to post-request to contain a field success. What's the best way to add this field there?
I use code like this to generate JSON responses:
try {
def entity = myService.saveEntity(arg1,arg2)
render entity as JSON //I want to add artificial field 'success = "yes"' here
} catch (ValidationException e) {
render parseErrors(e.errors) as JSON //field 'success = "no"' here
}
I just struggled with this exact issue this week. I wanted to send back a domain class as JSON but at the same time add an 'errorMessage' property that would potentially contain additional information.
Turns out that when using as JSON in grails it sends back a converter object, but its possible to turn that converter instance into a jsonObject using JSON.parse() which we can easily add new values to.
def jsonObject = JSON.parse((entity AS JSON).toString())
jsonObject.put("success", "yes")
render jsonObject as JSON
I think there are a couple of different approaches but this ended up being the easiest for me since I already have custom converters for most of my domain classes and I didn't want to add any other transient properties to my domain object.
Could you return a map containing the success field, and the object wrapped inside a separate variable:
try {
def entity = myService.saveEntity(arg1,arg2)
render [ success:'yes', val:entity ] as JSON
} catch (ValidationException e) {
render [ success:'no', val:parseErrors(e.errors) ] as JSON
}
Not tested it mind...
You can register your own JSON marshaller (at BootStrap.groovy, for example), like:
JSON.registerObjectMarshaller(MyEntity) { MyEntity it ->
return [
someField : it.someField, // you should specify fields for output, or put all '.properties'
success : true // as I understand you always have 'true' for real entity
]
}
where MyEntity is your class you want to use