Pass simple array to Java Spring - javascript

I'm trying to post a value and a string[] to Spring MVC. I either get:
HTTP Status 400 - Required String[] parameter 'testCaseNames' is not present
If I turn it to a list:
HTTP Status 400 - Required List parameter 'testCaseNames' is not present
What type should I put then??
var flowName = $('#flowName').val();
var testCaseNames = [];
$('.icons-right .action-icon:first-of-type').each(function() {
testCaseNames.push($(this).attr('name'))
});
console.log(testCaseNames);
$.ajax({
type: 'post',
url: '/create-flow/save',
data: {
flowName: flowName,
testCaseNames: testCaseNames
},
success: (function (result) {
})
});
#RequestMapping(value = "/create-flow/save" , method = RequestMethod.POST)
public #ResponseBody String saveFlow(HttpSession session, #RequestParam("flowName") String flowName, #RequestParam("testCaseNames") String[] testCaseNames)
{
String user = session.getAttribute("loggedUser").toString();
return TestFlow.addFlow(flowName,testCaseNames,user);
}
Output in console:
["sdad", "xzxc"]

You are posting the data as body of your REST request.
$.ajax({
type: 'post',
url: '/create-flow/save',
data: {
flowName: flowName,
testCaseNames: testCaseNames
},
success: (function (result) {
})
});
But in your controller you are recieveing as RequestParams.
#RequestParam("testCaseNames") String[] testCaseNames
That is the problem.
RequestParams are part of your url. For example if your url is like
http://blahbla:1234?abcd=1234&defg=5677
then abcd and defg are request parameters.(This is one way to send data)
Another way is to set the data in the Message Body which you don't see in the url, like how you are doing now.
You have two options to fix this
1. Change your ajax request to remove the data part and include testCaseNames and flowName in url like this
$.ajax({
type: 'post',
url: '/create-flow/save?flowName='+flowName+'&testCaseNames='+testCaseNames,
success: (function (result) {
})
});
2. Change your controller by removing the requestParams and creating a class with testCaseNames and flowName as fields and accept that as argument.
#RequestMapping(value = "/create-flow/save" , method = RequestMethod.POST)
public #ResponseBody String saveFlow(HttpSession session, #RequestBody SomeClass someclass)
{
.....
}
class SomeClass {
String flowName;
String testCaseNames; // Field Names should match exactly with what you send from frontend
// Gettter & Setters
}

You can try as follow
#RequestMapping(value = "/create-flow/save" , method = RequestMethod.POST)
public #ResponseBody String saveFlow(HttpSession session, #RequestParam("flowName") String flowName, #RequestParam("testCaseNames[]") String[] testCaseNameValues)
{
String user = session.getAttribute("loggedUser").toString();
return TestFlow.addFlow(flowName, testCaseNameValues,user);
}
And also add "[]" to Javascript field name
$.ajax({
type: 'post',
url: '/create-flow/save',
data: {
'flowName': flowName,
'testCaseNames[]': testCaseNames
},
success: (function (result) {
})
});

Related

How to use returned JSON.stringify array in C#

I have JavaScript function where I have an array and when I send that array to my C# controller, it should be in such way way that my controller should understand.
JavaScript function
function Check(obj) {
var eArray = $('..').map(function () {
return this.getAttribute("value");
}).get();
$.ajax({
url: "/Order/Check",
data: { GUID: JSON.stringify(eArray) },
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
});
My Controller
public ActionResult Check()
{
string guid = HttpContext.Request["GUID"];
var result = //send the result
return Json(result, JsonRequestBehavior.AllowGet);
}
I would like to get an array in my controller.
I'm not really sure what you are trying to achieve. From what I saw in your comments, you are sending an array of GUIDs to your controller, but that results in it being send as a string, and you want an array.
I tested your code and modified it a bit:
$.ajax({
type: "POST",
url: /your url/,
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
data: JSON.stringify({GUID: eArray}),
});
Where eArray is let eArray = ['D5FAF478-CF43-40E1-BE79-BB90147A3194', '2E79B23E-D264-4901-A065-7E0B7032A5D8']
Then, in my controller, I receive it as a model:
public class Dto
{
public string[] GUID { get; set; }
}
Then, you can use it like this:
[HttpPost]
public IActionResult Post([FromBody] Dto dto)
{
var listOfGuids = dto.GUID.Select(guid => Guid.Parse(guid)).ToList();
var result = Services.CheckRecords(listOfGuids);
...
}
It seems that unfortunately the standard JavaScriptSerializer.Deserialize doesn't handle Guid type.
Therefore, I would go with something like
public ActionResult Check()
{
string guidsStr = HttpContext.Request["GUID"];
var guids = new List<Guid>();
foreach (var guid in Regex.Replace(guidsStr, "[\\[\\\"\\]]", "").Split(",")) {
Guid newGuid;
if (Guid.TryParse(guid, out newGuid)) {
guids.Add(newGuid);
} else {
// handle invalid guide value
}
}
// guids list now contains parsed Guid objects
// do here what you need to do with the list of guids
return Json(result, JsonRequestBehavior.AllowGet);
}
Please let me know if this helps.

How to pass HttpPostedFileBase from JavaScript as model instead of FormData

Is it possible to pass the form data with out using FormData by using the JavaScript Model. As my form has many controls I would like to go with Model approach instead of FormData.
Is there a way to pass selected files to controller with out using HttpPostedFileBase? I have nearly 10 different class which accepts HttpPostedFileBase
I have a class as follows in c#
public class ArtGallery{
Public string GallerName {get;set;}
Public HttpPostedFileBase[] Documents {get;set;}
}
The equivalent JavaScript Model is
class ArtGallery{
GallerName;
Documents[];
}
On my save of the form here is how I am doing it
function saveFormData(){
let gallery = new ArtGallery();
gallery.GallerName = "Test";
$.each($("input[type=file]"), function (i, obj) {
$.each(obj.files, function (j, file) {
gallery.Documents.push(file);
});
});
saveToDb();
}
function saveToDb() {
let url = "/MyController/PostData/";
$.ajax({
url: url,
type: 'POST',
async: false,
data: '{gallery : ' + JSON.stringify(gallery) + '}',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
},
error: function (request) {
}
});
}
My controller is as follows, which is getting triggered but documents I am unable to get
[HttpPost]
public JsonResult PostUserData(ArtGallery gallery) {
}

Sending a string with Ajax to controller

My knowledge of Spring boot is very low.
I have made a table in HTML, which when I click on, an event is sent to a Javascript function, in which I try to catch the Id (a string) of the cell and send it to the controller. I tried many examples from internet but none worked for me, can anyone help me please?
The id is being caught correctly by mouse click, but I have a problem with sending.
This is my JSP
<c:forEach items= "${rooms2}" var="m" >
<tr>
<td style="background-color:OldLace">${m.day }</td>
<c:choose>
<c:when test="${m.hour1confirm==false}">
<td style="background-color:green" id="${m.hour1}" onclick=
"content(this)" >${m.hour1 }</td>
...
<script >
// <script type="text/javascript">
function content(elem)
{
// $(document).ready(function()
// {
// // PREPARE FORM DATA
// var idt =elem.id;
// console.log(idt);
// // DO POST
// $.post({
// type : "POST",
// url :"reservation2",
// // contentType: "application/json",
// data : JSON.stringify(idt),
// dataType : 'json',
// })
// });
var idt =elem.id;
console.log(idt);
$.ajax({
url:"reservation2",
type: 'POST',
data: idt,
dataType: "text",
contentType: false,
mimeType: false,
success: function(response){
console.log(data);
return false;
}
});
}
</script>
this is controller
.
.
.
// #RequestMapping(value = "/reservation2", method = RequestMethod.POST)
// public String reservation2(#ModelAttribute("idt") String idt , Model model) {
// return "Reservation2";}
#RequestMapping(value = "/reservation2", method = RequestMethod.POST)
public #ResponseBody
String Submit(#RequestParam("idt") String idt) {
// your logic here
return "reservation2";
}
#RequestMapping(value = "/reservation2", method = RequestMethod.GET)
public String reservation(Model model) {
List<Room> rooms2= new ArrayList<>();
System.out.println(rooms2);
rooms2= x.findAll();
model.addAttribute("rooms2", rooms2);
return "reservation2";
...
when I run I get this error in console :
POST http://localhost:8080/reservation2 403 ()
I believe you are not sending the right parameter along the way. When you do the ajax post request, in the field data can you specify the name of the parameter you are sending?
Can you try this one
$.ajax({
url:"reservation2",
type: 'POST',
data: {"idt": idt},
dataType: "json",
contentType: "application/json",
success: function(response){
console.log(data);
return false;
}
});
Try changing your request to something like this
$.ajax({
url: "/reservation2", //added '/' in the beginning
type: 'POST',
data: idt,
dataType: "text",
contentType: "text/plain", //change
//mimeType: false, //remove
success: function(response) {
console.log(data);
return false;
}
});
and your controller to this
#RequestMapping(value = "/reservation2", method = RequestMethod.POST)
public String reservation2(#RequestBody String idt)
{
// your logic here
return "reservation2";
}

ajax post request with multiple paramaters

My controller:
[HttpPost]
public IActionResult UserRoleChanged(string roleName,string userName)
{
var a = roleName;
var b = userName;
return RedirectToAction("UserManager");
}
Script in view:
if (window.confirm('Are you sure that you want to change role?')) {
jQuery.ajax({
type: "POST",
url: "#Url.Action("UserRoleChanged", "DashBoard")",
dataType: 'json',
data: { 'roleName': this.text, 'userName': 'SomeName'},
cache: false,
success: function (data){
window.location.href = data;
},
failure: function (data) {
}
})};
When I run script above UserRoleChanged action does not invoke. If I try to remove userName variable from data in ajax then UserRoleChanged action method invokes without any problem. How can i pass multiple data to my controller? What is wrong with my code?
Remove the dataType: 'json' from the ajax, and try again. As you are trying to get the values on server side as normal variable, so dataType: 'json' is not required here.
You can create a model with same properties and pass it as a parameter. Its a good practice.
Looks like this.
public class User
{
public string RoleName { get; set; }
public string UserName { get; set; }
}
And the json looks like this example
{
"RoleName" : "somename",
"UserName" : "somename"
}

Why ModelBinding don't work with FormData but works with RequestPayload?

I have been working with Web API and found an interesting observation that I am not able to understand.
controller:
public class UserController: ApiController
{
public void Post(MyViewModel data)
{
//data is null here if pass in FormData but available if its sent through Request Payload
}
}
viewModel
public class MyViewModel{
public long SenderId { get; set; }
public string MessageText { get; set; }
public long[] Receivers { get; set; }
}
JS that is not working
var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");
$.ajax(
{
url: '/api/User',
type: 'POST',
data: JSON.stringify(usr),
success: function(response) { debugger; },
error: function(error) {debugger;}
});
JS that is working
var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");
$.post( "/api/User", usr)
.done(function( data ) {
debugger;
});
So, if I pass on $.ajax with lots of other configuration like type, contentType, accept etc, it still don't bind model correctly but in case of $.post it works.
Can anybody explain WHY?
Try looking at what gets POSTed when you try it with $.ajax (e.g. with Fiddler of F12 tools of your choice). It can very well be that jQuery passes the data as URL-encoded string rather that as JSON literal.
To fix the issue try specifying dataType together with contentType parameter. Also, I don't think you need JSON.stringify, just pass the JSON literal you're creating:
$.ajax({
data: usr,
dataType: 'json',
contentType: 'application/json',
/* The rest of your configuration. */
});
Here's the TypeScript method that we use in one of our projects (ko.toJSON returns a string representing a JSON literal passed as a method parameter):
public static callApi(url: string, type?: string, data?: any): RSVP.Promise {
return new RSVP.Promise((resolve, reject) => {
$.ajax('/api/' + url, {
type: type || 'get',
data: data != null ? ko.toJSON(data) : null,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: () => {
resolve.apply(this, arguments);
},
error: () => {
reject.apply(this, arguments);
}
});
});
}
Hope this helps.

Categories