RequestBody is null in controller - javascript

I'm trying to send JSON object from frontend to backend via jQuery AJAX.
The ajax call is performed successfully on the requested path "/survey" with a POST method.
Problem is, my #RequestBody final HmmSurveyForm hmmSurveyForm has null values for my fields "answer1" and "heading".
When I checked request in google chrome developer request is sent:
But the response is null for populated fields from frontend:
I have following code in frontend:
postSurvey: function() {
$.ajax({
url: this.encodedContextPath + "/survey",
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: ACC.hmmSurvey.getJSONDataForSurvey(),
async: true,
success: function (response) {
console.log(response);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("The following error occurred: " + textStatus, errorThrown);
}
});
}
getJSONDataForSurvey: function () {
var json = [];
json.push({"answer1": "1"});
json.push({"heading": "Test"});
return JSON.stringify({"hmmSurveyForm": json});
}
and in backend:
#RequestMapping(value = "/survey", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody HmmSurveyForm postSurvey(#RequestBody final HmmSurveyForm hmmSurveyForm, final Model model) {
System.out.println(hmmSurveyForm);
return hmmSurveyForm;
}
public class HmmSurveyForm {
private String heading;
private String answer1;
// getter, setters
}

You are declaring your RQ body incorrectly in JS
var json = [];
json.push({"answer1": "1"});
json.push({"heading": "Test"});
console.log({"hmmSurveyForm": json});
which has the root hmmSurveyForm as an array of distinct objects, which has no relation to what your backend expects.
You should be using the code below;
var json = {};
json["answer1"] = "1";
json["heading"] = "Test";
console.log({"hmmSurveyForm": json});
Check more on JSON Object in JS here

Related

Ajax POST an object with javascript, but the value in backend is null, why?

So on button click there is a function sendEmail(). Alert is working fine, I can see my datas there. But on backend I can't see anything, just everything is null.
function sendEmail() {
var datas = new Object();
datas.mail = $('#contactDropdownList').val();
datas.mailobject = $('#emailObject').val();
datas.text = $('#emailText').val();enter code here
alert(datas.mail + datas.mailobject + datas.text);
$.ajax({
type: "POST",
dataType: "json",
url: "/Email/sendEmail",
contentType: 'application/json; charset=UTF-8',
data: JSON.stringify({ items: datas }),
success: function (data) {
console.log(data);
//do something with data
},
error: function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
}
});
}
C# code:
public class MyClass
{
public string Email { get; set; }
public string Object { get; set; }
public string Text { get; set; }
}
[HttpPost]
public IActionResult sendEmail(MyClass items)
{
return Json(new { data="Ok" });
}
items.Email, items.Object and items.Text are null.
And the return valu is null as well, because in javascript success: function (data) { console.log(data);
is empty string.
What can be the problem? Thank you!
Model binder expects json content to match C# class. Your datas object should look like that
var datas = {
email: $('#contactDropdownList').val(),
object: $('#emailObject').val(),
text: $('#emailText').val()
}
Since you wrapped your object ({ items: datas }), you may think it will be mapped to sendEmail(MyClass items), but in reality items name does not matter, you can change variable name to any other name you like
Make sure you apply [FromBody] attribute to your parameter like that
[HttpPost]
public IActionResult sendEmail([FromBody]MyClass items)
Complete demo:
<script>
function sendSmth() {
var data = {
Email: 'email',
Object: 'object',
Text: 'text'
};
$.ajax({
type: "POST",
dataType: "json",
url: "/home/index",
contentType: "application/json",
data: JSON.stringify(data),
success: function (datas) {
console.log(datas)
}
})
}
</script>
And controller
[HttpPost]
public IActionResult Index([FromBody]MyClass obj)
{
return View();
}
As someone has noted, you have a mismatch between what you're sending to the controller and what the model the modelbinder is expecting. You can also vastly simply your AJAX code:
function sendEmail() {
var data = {
Email: $('#contactDropdownList').val(),
Object: $('#emailObject').val(),
Text: $('#emailText').val()
};
$.post("/Email/sendEmail", data)
.done(function (response) {
console.log(response);
//do something with response
})
.fail(function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
});
}
You don't really need to specify the content type or data type - the $.post helper's defaults work just fine for what you've shown.

Send ararylist from js to spring controller

I want to send an arrayList from javaScript to spring controller, I have written this code but it doesn't work, when I call this function nothing happens.
function order_(){
var itemOrder = $('#sortable').sortable("toArray");
$.ajax({
contentType:"application/json;",
type : "POST",
url : "/my_url",
data : (itemOrder),
dataType: "json",
success: function (data) { alert("Mapping Successful") },
failure: function (data) { alert("not working..."); }
});
}
My spring controller
#RequestMapping(value = "/my_url", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String getItemOrder(#RequestBody String[] itemOrder) {
// code to get itemOrder }
Is there something wrong in this code?

How to pass a list from spring controller to ajax in jquery

This is my Jquery! Here i am not getting success response, instead a error response is thrown when a list is returned from controller to below jquery. Please let me know where i am going wrong.
//ajax method to retrieve the data from controller where controller returns list
function doAjaxPost() {
// get the form values
var pid = $('#pid').val();
$.ajax({
type: "GET",
url: "http://localhost:8085/HMS/iochart1.html",
data: "pid=" + pid,
success: function (response) {
alert(response.list4);
$.each(response, function (index, datec) {
alert(datec.name); //to print name of employee
});
},
// Even though controller returns the list,but i am not getting the above success response,instead below error method is executed.
error: function (e) {
alert('Error: ' + e);
}
});
}
Below is the controller which returns the list.
#RequestMapping(value="/iochart1", method = RequestMethod.GET)
public #ResponseBody List<Iochart> iochart1(#ModelAttribute("s") Iochart s) {
System.out.println("Patient"+s.getPid());
List<Iochart> list4 = dao.getPatientdet1(s.getPid());
return list4;
}
getPatientdet1() which retrieves the data from database
public List<Iochart> getPatientdet1(String pid) {
// TODO Auto-generated method stub
System.out.println(pid);
return template.query(
"select pid,name,fileno,age,gender,date,wardno,doctord,doctsig,ratef,nursesig,time,type,amount,typecommence,amtgiv,urine,vomitus,remarks from iochart where pid='"+pid+"'",
new RowMapper<Iochart>() {
public Iochart mapRow(ResultSet rs, int row) throws SQLException {
Iochart i = new Iochart();
i.setPid(rs.getString(1));
i.setName(rs.getString(2));
i.setFileno(rs.getString(3));
i.setAge(rs.getString(4));
i.setGender(rs.getString(5));
i.setAdmdate(rs.getString(6));
i.setWardno(rs.getString(7));
i.setDoctord(rs.getString(8));
i.setDoctsig(rs.getString(9));
i.setRatef(rs.getString(10));
i.setNursesig(rs.getString(11));
i.setTime(rs.getString(12));
i.setOraltype(rs.getString(13));
i.setOralamt(rs.getString(14));
i.setOralcommence(rs.getString(15));
i.setAmtgiv(rs.getString(16));
i.setUrine(rs.getString(17));
i.setVomitus(rs.getString(18));
i.setRemarks(rs.getString(19));
System.out.println(rs.getString(2));
return i;
}
}
);
}
Change your controller method like so. Mind the #RequestParam that is used to get the pid
#RequestMapping(value="/iochart1", method = RequestMethod.GET)
public #ResponseBody List<Iochart> iochart1(#RequestParam(name = "pid") String pid) {
return dao.getPatientdet1(pid);
}
And your ajax url like so
function doAjaxPost() {
// get the form values
var pid = $('#pid').val();
$.ajax({
type: "GET",
url: "http://localhost:8085/HMS/iochart1", //Don't postfix .hmtl
data: "pid=" + pid,
...
});
}

Ajax GET call to webAPI

In my javascript file i am trying to make a GET Request to my webAPI, the entire request is ignored. the two alerts before and after the request are outputted but nothing within my request.
This is my GET request made in my javascript file:
alert("before Get");
$.ajax({
url: '/api/Map/',
type: 'GET',
dataType: 'json',
success: function (data) {
alert(data);
},
error: function () {
alert("error in request");
}
});
alert("after Get");
My WebAPI file and the method im trying to get:
// GET: api/Map
public IEnumerable<string> Get()
{
SetContext();
List<ICoordinate> BoundingBox = CreateBoundingBox(_LoadedConfiguration.StartPosition);
List<string> LayerNames = _LoadedConfiguration.GetAllLayerNames();
Map LoadedMap = new Map(BoundingBox, LayerNames, _persistenceFactory, _LoadedConfiguration);
GeoJson.IGeoJsonGeometry MapFeatureCollections = (IGeoJsonGeometry)LoadedMap.GetAsGeoJsonObject();
return new string[] { MapFeatureCollections.ToString()};
}
I am trying to return the string of "MapFeatureCollections"

Post files and object in the same AJAX request

I have some data and files that should be posted in one same AJAX request. Tried some solutions but I always get null in the controller (files are sent fine and when I change Tester class to simple string it also works).
My JS:
function sendAjaxWithFile (formData, successCallback, errorCallback) {
successCallback = successCallback || function () { };
errorCallback = errorCallback || function () { };
$.ajax({
url: "/Test/Save",
type: "POST",
data: formData,
cache: false,
processData: false,
contentType: false,
success: successCallback,
error: errorCallback
});
}
var data = new FormData();
data.append("tester", { Name: "QWERTY" });
data.append("someFile", file);
$scope.sendAjaxWithFile(data, function (response, textStatus, jqXHR) {
}, function (jqXHR, textStatus, errorThrown) {
});
And the server side code:
[AjaxOnly]
[HttpPost]
[Route("Save")]
public async Task<JsonResult> Save(Tester tester, HttpPostedFileBase someFile)
{
return await Task.FromResult(Json(0));
}
Tester class:
public class Tester
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
I did a workaround, because I don't think it can be resolved in a normal way...
My solution is to send string data which is serialized from my JS object.
data.append("serializedJsonString", JSON.stringify({ Name: "QWERTY" })); // I can serialize what I want to
I needed to change the parameter of my Save method to get JSON string data and convert it into Tester class manually:
[AjaxOnly]
[HttpPost]
[Route("Save")]
public async Task<JsonResult> Save(string serializedJsonString, HttpPostedFileBase someFile)
{
var decodedJson = HttpUtility.UrlDecode(serializedJsonString);
var jTester = JObject.Parse(decodedJson);
var tester = new Tester { Name = jTester["Name"].ToString() };
return await Task.FromResult(Json(0));
}

Categories

Resources