Json response looks empty when called from controller otherwise working fine - json

When I directly type the url for json response in browser I get the correct response printed in browser in JSON but with same URL is called by clicking on a button then response looks to be empty.
Here is my controller:
#RequestMapping(value="/ShowAllCustomers", method = RequestMethod.GET)
public #ResponseBody Customer AllCustomersList() {
Customer customer=customerService.findById(1);
return customer;
}
And here I am trying to get response:
<script type="text/javascript">
function startAjax() {
$.ajax({
type : 'GET',
url : 'customers/ShowAllCustomers',//this is url mapping for controller
dataType: 'json',
success : function(response) {
alert(response);
alert(response.first_name);
//this response is list of object commming from server
}
});
}
</script>
Here is button code which is pressed:
<input type="button" value="Customers" onclick="startAjax();"/>
But when I click on button I see no alert message on screen.
Any solution please?

First verify that the URL called by jQuery is the same as the one that you call by hand in the browser.
You can do so, in Chrome, by pressing F12, click on the Network tab, and after clicking the button, verify that the URL was called and was the correct one, and clicking on it verify if there is any response.
On the Java side, you can add logging when your method is called, but to start I think it's better that you verify what's happening on the JavaScript side.
Also check the Console tab, you might have a JavaScript error, that prevents further code execution.
Good luck.

Related

MVC - returning data via ajax call renders it as page

New to MVC.
Scenario is. Using a 3rd party upload library for images. When a form is submitted, I want to make a call via ajax to submit the data and return the inserted item id. I then use that id for the 3rd party upload library to build folders where the images will be uploaded to.
I have the ajax call working and inserting the data to the database and getting the inserted id. But when the debug returns from the controller, it renders the id as a whole page.
Missing something fundamental here to MVC I think.
cshtml file:
<div class="col-md-8">
<input type="submit" value="Add Item" id="submitItem" />
<script>
$(document).ready(function () {
$("#submitItem").submit(function () {
event.preventDefault();
insertData();
});
});
function insertData()
{
var requestData = {
userID: $("#hdnUserID").val(),
title: $("#title").val(),
typeID: $("#typeID").val(),
description: $("#description").val()
};
$.ajax({
url: '<%= Url.Action("ItemUserDashBoard", "Home") %>',
type: 'post',
data: JSON.stringify(requestData),
dataType: 'json',
success: function (data) {
// your data could be a View or Json or what ever you returned in your action method
// parse your data here
alert(data);
$("#fine-uploader-gallery").fineUploader("uploadStoredFiles");
},
processData: false
});
}
</script>
</div>
HomeController.cs
[HttpPost]
public JsonResult ItemUserDashBoard(ItemAppraise.Models.iaDashBoardModel objItemUserDashBoard)
{
if(ModelState.IsValid)
{
using (dbContext)
{
ia_items iaItem = new ia_items
{
userID = objItemUserDashBoard.iaItems.userID,
typeID = objItemUserDashBoard.iaItems.typeID,
title = objItemUserDashBoard.iaItems.title,
description = objItemUserDashBoard.iaItems.description,
lastUpdate = DateTime.Now
};
dbContext.ia_items.Add(iaItem);
dbContext.SaveChanges();
//objItemUserDashBoard.iaItems.itemID = iaItem.itemID;
return Json(iaItem.itemID.ToString());
}
}
else{
return null;
}
}
Fiddler shows it as having a header of Content-Type: application/json; charset=utf-8.
But the page renders under the control url 'http://localhost:55689/Home/ItemUserDashBoard' with just the item id showing.
How do I get the data back just to use in the success part of the ajax call and not be rendered? Is this Partial Views or something similar?
Any guidance is appreciated.
In standard MVC. Any call made to a controller is handled just like a web request. So if i understand you correctly - the result of your httpPost is being rendered instead of the desired View? This is because you are returning JSON, so the controller assumes that is what you are trying to render. If you want a View to be rendered instead (and somehow use that response data) you could try setting the return type to ActionResult and returning a View("nameofview"); You can pass your response data to that view in a number of ways.
As a side note I think the problem you are facing could be better solved with Web Api instead of MVC. It works well with MVC and could be a simpler way of implementing your desired functionality. Separating your post requests and database interactions from the logic which decides which View to return.

submitting a form works in some instances, but returns error 403 in other instances

I have an mvc3 application which makes use of an ajaxsubmit to a controller action.
The <form> opening tag in my page appears like this:
<form action="/application/home/Save?Length=0" class="form-horizontal" data ajax="true" data-ajax-method="POST" data-ajax-mode="after" data-ajax update="#jsonResult" enctype="multipart/form-data" id="inputForm" method="post" role="form">
If i submit this form from within the network that the server is based, the post request will always work. But if i submit the form externally, on occasions i get this generic error:
403 Forbidden: You don't have permission to access /application/home/Save on this server.
The above error doesnt always occur. only in particular instances.
Upon analysing the request headers, The only difference i see is Content-length:
They have the following:
The only other difference that i think could be the cause of this issue is in one of the fields in the request payload.
Now one of the fields i pass to the server is in a special code that has tilders and carrot symbols. Here is an example:
------WebKitFormBoundaryvvviIpe8b82tAvOd
Content-Disposition: form-data; name="udfArray"
["1~d^testfield~d^R"]
Whenever the form submit fails, it happens to have the above form data. When it succeeds, the field is set to []
The trouble is, i dont understand why having the code set to ["1~d^testfield~d^R"] should be an issue if it works within the network.
If anyone could point me in the right direction for making this work externally that would be great.
Here is my submit code:
//options for submit action
var options = {
data: {
udfArray: ko.toJSON(self.TempArray()),
title: self.title(),
given_name: self.givenName(),
//... other fields
},
uploadProgress: function () {
},
dataType: "json",
success: function (result) {
//do something
}
};
$('#inputForm').ajaxForm();
$('#inputForm').unbind('submit').submit(function () {
$('#loadingDiv').show();
$(this).ajaxSubmit(options);
return false;
});

calling REST service on form submit

I am trying to call service http://localhost:8080/app/search It gets data in RequestBody as
{
"skills":["c","java"],
"country":["India"],
"state":["Maharashtra","Gujrat"],
"city":["Mumbai","Pune"],
"highestDegree":["MCA","BE"],
"functionalArea":["IT"],
"functionalRole":["Tester"]
}
and header Content-Type:application/json
I tested above service with Postman and it gives me correct output. Now i tried to call above service from html form its giving me error that request is syntactically incorect.
My HTML form is
<form method="POST" action="http://localhost:8080/app/search">
<!--(form ellements with multiple select textbox )-->
</form
Is it right way or I need model from backbone?
It's a wrong way, you have to create a Model and set it's url to your service :
var MyModel = Backbone.Model.extend({
url: '/app/search'
});
and when you click the submit button catch it in your view, set the form data in your model and call it's save function.

Handling a checkbox form in a dialog with Spring MVC

There are plenty of tutorials out there showing how to build a form with a simple POJO model object and the "command" property on the Spring taglib.
Examples: A tutorial
I seem to thrive on making my life hard, though and have my form running in a jQuery dialog box...whose checkbox statuses are pre-processed with a javascript function. I'm doing this through AJAX calls in that javascript function.
Sooo, my form init looks like this:
<form:form action="javascript:associateArtifacts()">
This invoked my javascript method:
function associateArtifacts(){
/* JSONIFY the list of checked boxes and send that data to the server here in an AJAX call */
var artifacts = [];
$('#artifacts_container input:checkbox').each( function(j,listitem) {
artifacts.push(listitem.name);
});
$.ajax({
type: "POST",
url: "associateArtifacts.html",
data:JSON.stringify(artifacts),
success: function(html){
alert( "Submitted");
}
});
return false;
}
The point of this is building a dialog with a list of checkboxes that are checked based on DB data that the user can modify then save back to the server.
My issue is, I'm getting the dialog up and populated with the checkboxes and loaded with the values, but I seem to have not thought it through as I have no idea how to intercept the data coming to the server as JSON and process it.
In the past I've done this with URL'd parameters, but in this case is a variably-sized large string of JSON data.
Am I going to be forced to define an object that just hold a single List in it for my Spring MVC container to assign this JSON data to? Seems kind of ridiculous...
Thoughts? Suggestions? Harsh criticisms for going at this entirely wrong?
Thanks for any of the above.
EDIT
Signature looks like this:
#RequestMapping(value = "/associateArtifacts.html", method = RequestMethod.POST, headers = {"content-type=application/json"})
public void associateArtifacts(#RequestBody List<String> checkboxData){
Client from data in Chrome Tools looks like this:
["checkboxTitle1","checkboxTitle2","checkboxTitle3"]:
Which is produced by my client when I take my array of checkBox names and do this to it:
JSON.stringify(arrayOfNames)
Current error is:
HTTPStatus 415 - The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.
EDIT #2
It was the lack of contentType on my AJAX call, as you suggested. Thanks.
Assuming your JSON is something like this:
"[{checkbox1: 'true'}, {checkbox2: 'false'}]"
Firstly include jackson-mapper-asl on your classpath:
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>
Post using JQuery ajax like this:
$.ajax({
type: "POST",
url: "associateArtifacts.html",
data: JSON.stringify(artifacts),
contentType: 'application/json',
success: function(html) {
alert("Submitted");
}
});
And define your Spring MVC controller handler method like this:
#RequestMapping(value = "/associateArtifacts.html", method = RequestMethod.POST, headers = {"Content-type=application/json"})
#ResponseBody
public MyResponse associateArtifacts(#RequestBody List<Map<String,String>> checkboxData) {
// .. process the data here
}
The JSON string will be automatically bound into a list of map (key value pair).
The #ResponseBody annotation will cause the returned MyResponse object to be serialized into JSON

Chrome API responseHeaders

Based on this documentation: https://developer.chrome.com/extensions/webRequest.html#event-onHeadersReceived
I tried to display the response via the console like:
console.log(info.responseHeaders);
But its returning undefined.
But this works though:
console.log("Type: " + info.type);
Please help, I really need to get the responseHeaders data.
You have to request the response headers like this:
chrome.webRequest.onHeadersReceived.addListener(function(details){
console.log(details.responseHeaders);
},
{urls: ["http://*/*"]},["responseHeaders"]);
An example of use. This is one instance of how I use the webRequest api in my extension. (Only showing partial incomplete code)
I need to indirectly access some server data and I do that by making use of a 302 redirect page. I send a Head request to the desired url like this:
$.ajax({
url: url,
type: "HEAD"
success: function(data,status,jqXHR){
//If this was not a HEAD request, `data` would contain the response
//But in my case all I need are the headers so `data` is empty
comparePosts(jqXHR.getResponseHeader('redirUrl')); //where I handle the data
}
});
And then I silently kill the redirect while scraping the location header for my own uses using the webRequest api:
chrome.webRequest.onHeadersReceived.addListener(function(details){
if(details.method == "HEAD"){
var redirUrl;
details.responseHeaders.forEach(function(v,i,a){
if(v.name == "Location"){
redirUrl = v.value;
details.responseHeaders.splice(i,1);
}
});
details.responseHeaders.push({name:"redirUrl",value:redirUrl});
return {responseHeaders:details.responseHeaders}; //I kill the redirect
}
},
{urls: ["http://*/*"]},["responseHeaders","blocking"]);
I actually handle the data inside the onHeadersReceived listener, but this way shows where the response data would be.