Sending a string to ActionResult using ajax - javascript

I am trying to send a string to my ActionResult in the controller. I have followed many tutorials and read hundreds of stackoverflows but can't get it to work. I am trying to send a string with the value of a radiobutton.
My ActionResult code is:
[HttpPost]
public ActionResult Opslaan(string theStatus)
{
if(theStatus!= null)
Database.UpdateAanvraagStatusByGuid(Session["Guid"].ToString(), theStatus);
return new RedirectResult(Request.UrlReferrer.OriginalString);
}
My code to send the variable via AJAX:
$("#opslaan").click(function (e) {
e.preventDefault();
var theStatus = $('input[name=StatusOptions]:checked').val();
$.ajax({
type: "POST",
url: "/Aanvraag/Opslaan",
data: theStatus,
success: function (result) {
if (result.Success) {
alert("Uw wijzigingen zijn opgeslagen.");
} else {
alert(result.Message);
}
}
});
});
When I click my button called "opslaan" the program does not execute te AJAX. Alerts around it do go off.
Thanks in advance :)

Edit Fabio's answer like this:
$("#opslaan").click(function (e) {
e.preventDefault();
var theStatus = $('input[name=StatusOptions]:checked').val();
$.ajax({
type: "POST",
url: "/Aanvraag/Opslaan?theStatus= " + theStatus ,
//data: { 'theStatus': theStatus } ,
success: function (result) {
if (result.Success) {
alert("Uw wijzigingen zijn opgeslagen.");
} else {
alert(result.Message);
}
}
});
});
Note the query string at the end of the url property. Even though string IS a nullable type, if you don't have any route configuration like "/Aanvraag/Opslaan/theStatus", the routing system will not find a match.
There are a few things to note here:
Your original solution DID show an alert, that means a request went to the server, and a response has arrived.
Fabio's answer didn't work because you (as I guess) don't have any route like "/Aanvraag/Opslaan/theStatus". Even though string is a nullable type - so the routing system will allow a string parameter to have no incoming value from the request - the url parameter set by the client told the routing system 'Hey please forward me to something that is configured to a url like "/Aanvraag/Opslaan/theStatus"'. I am sure You don't have any route set up with that pattern so the routing system will fail to find a matching Controller/Action method pair, that results in a 404.
Your original solution didn't cause this problem, because you sent the theStatus parameter as data, and your url was "/Aanvraag/Opslaan". This means even the default route will be able to find out that the Controller is 'Aanvraag' and the controller is 'Osplaan'. From then on, Model Binding was able to bind your theStatus parameter to the action method parameter. (If it wasn't, the proper action method would strill be called, just with a null value given to the parameter.) However, your response didn't send any object with property Success back, so your if statement went to the else branch.
All in all, you can either send the theStatus parameter as data and let the model binding system to bind it to your action method parameter, or use routing to do that for you. In this latter case, you must either configure a proper routing entry or use a query string like in my modified version.
For the if statement to work, you need to send back something that does have a Success property, like Fabio did.

It might be helpful:
[HttpPost]
public ActionResult Opslaan(string id)
{
if(id != null)
Database.UpdateAanvraagStatusByGuid(Session["Guid"].ToString(), id);
// do your logic to check if success is true or false
return Json(new { Success = true, Message = "something" });
}
Javascript:
$("#opslaan").click(function (e) {
e.preventDefault();
var theStatus = $('input[name=StatusOptions]:checked').val();
$.ajax({
type: "POST",
url: "/Aanvraag/Opslaan/ " + theStatus ,
//data: { 'theStatus': theStatus } ,
success: function (result) {
if (result.Success) {
alert("Uw wijzigingen zijn opgeslagen.");
} else {
alert(result.Message);
}
}
});
});
EDIT
Just to see if it works, change the name of the parameter in the Action and Javascript.

Related

Why ajax call send null to servlet? [duplicate]

This question already has answers here:
How should I use servlets and Ajax?
(7 answers)
HTTP request parameters are not available by request.getAttribute()
(1 answer)
Closed 3 years ago.
I'm trying to send the username to the servlet through an ajax call to check its availability, but the servlet show a null pointer exception.
I've also tried with the XMLHttpRequest instead of $.ajax.
This is my Javascript file:
$(document).ready(function() {
$("#reg-form").submit(function() {
var res = true;
if (!testUser()) {
res = false;
$("#erruser").css("display", "block");
$("#username").addClass("errclass");
} else {
$("#erruser").css("display", "none");
$("#username").removeClass("errclass");
}
return res;
});
});
function testUser() {
var el = $("#username").val();
var b = false;
$.ajax({
type: "POST",
url: "CheckUserServlet",
data: { user: el },
dataType: "json",
success: function(bool) {
alert(bool);
if (bool == "si") b = true;
},
error: function() {
alert("errore");
}
});
return b;
}
This is my servlet doPost method:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getAttribute("user").toString();
System.out.println("username servlet= "+username);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
if (!ud.doRetrieveByUser(username)) {
response.getWriter().write("si");
return;
}
response.getWriter().write("no");
return;
}
Thanks!
CLIENT SIDE
Your test user function will always return false regardless of if the server is operating correctly because $.ajax() is an async function. There are a few ways around this. In your case, without knowing much more about what you are building, I would suggest removing the return value from your test user function, and moving your logic into the success/failure areas in the ajax callback. This way, the ajax call just does it's thing and lets the success function modify your page however you want.
function testUser() {
var el = $("#username").val();
$.ajax({
type: "POST",
url: "CheckUserServlet",
data: { user: el },
dataType: "json",
success: function(bool) {
alert(bool);
// put logic here
if (bool === "si") {
$("#erruser").css("display", "block");
$("#username").addClass("errclass");
} else {
$("#erruser").css("display", "none");
$("#username").removeClass("errclass");
}
},
error: function() {
alert("errore");
}
});
}
I would also suggest setting up the initial state of your page so that while this request is happening the user is shown something that makes sense. Answer the following question: "what do I show my users when the page does not know yet if it is a test user" and then set the initial state of the page accordingly
SERVER SIDE
I've always found interacting with java & JSON data a bit clunky, and your issue seems like something I've grappled with in the past.
Your question is "why is ajax sending null to the server". It may seem like that but what is really happening is that your server doesn't understand how to interpret the data it is getting. Take a look at this question about getting a JSON payload.. You need to tell your server how to parse the data coming from the client. If you were to inspect the data being sent, I would expect it looks something like this {"user":"blablabla"}.
If you have a class definition already, use that. For this I am using something that looks like this:
public class UserRequest {
String user;
}
// get the body as a string. Requires https://commons.apache.org/proper/commons-io/
String body = IOUtils.toString(request.getReader())
// parse the json with gson. Requires https://github.com/google/gson
Gson g = new Gson();
User u = g.fromJson(body, UserRequest.class);
String username = u.user;

posting one value using ajax (frontend)

I have a problem with connection frontend-backend. I would like to send one value (radio1Value) from javascript function (on click) using jquery ajax. This function should look like I have wrote?
If yes how should REST look in Java? Should this number that backend have received be in function Get() as a parameter?
$.ajax({
url: "someurl",
method: "post",
data: radio1Value
success: function (response) {
alert("Success!");
}
});
#GET
#Path("/{ship}")
public int Get(){
//check in matrix if number from radiovalue exists
}
After checking I would like to send response from backend to frontend.
After advices here what I have got:
$("th").click(function(){
event.preventDefault();
var radio1Value;
var ifEnoughShips;
radio1Value = $("input[name='stat']:checked").val();
//sending radiovalue
$.ajax({
url : "localhost:8126/ship",
method : "get",
data : radio1Value
success: function (response) {
alert("Success!");
ifEnoudhShips=response;
)};
)};
-------------------------
//REST
public class RestTest{
#GET
#Path("abc/{ship}") //here I am not sure because I dont wanna use path
public int CheckHowMany(#PathParam("ship") Integer ship){
Checker ch1 = new Checker();
int res=ch1.CheckNumber(ship);
return res; //0 if number doesn't exists 1 if it does
}
}
You can use the #PathParam notation.
#GET
#Path("/{ship}")
public int Get(#PathParam("ship") Integer ship){
//check in matrix if number from radiovalue exists
return 1; // Return your success int
}
After you are done in your function you can return anything you want to the frontend. Also when you are using ajax make sure you are calling your backend via a GET method and appending the parameter in the call url.
$.ajax({
url: "someurl",
type: "get", //send it through get method
data: radio1Value,
success: function(response) {
//Do Something
},
error: function(xhr) {
//Do Something to handle error
}
});
I am assuming that url : "someurl", is just a placeholder and will actually contain the correct value. Make sure that you're sending the request to http://yourdomain.top/ship since ship is the URL that your Java framework listens to (#Path("/{ship}")
You need to set the correct method header.
You're sending method : "post", while your Java endpoint expects #Get. The Java framework will probably not match the POST request with a GET action.
You need to receive a parameter that the Java framework you are using will be able to bind it to. Probably you need to do this:
#GET
#Path("/{ship}")
public int Get(string radio1Value) {
//check in matrix if number from radiovalue exists
}
What you need to fix is:
Use the correct URL
Use the correct method (use GET or POST in both the request and action)
Have the action receive a parameter so the value you send is obtainable
Edit: for the onclick part you need to wrap your ajax request into an event using jQuery (since you're using this library). You do this like this:
<button id="execute_on_click">Send request</button>
and in your javascript:
$("#execute_on_click").click(function(event) {
event.preventDefault();
$.ajax({
url: "localhost:8126/ship",
method: "get",
data: radio1Value
success: function (response) {
alert("Success!");
}
});
});

Controller Action method return string or Redirect to another action with ajax post request

I am calling MVC action method through jquery ajax post. This action method will either return a string value or if certain condition in action method is true it will redirect to another action method. The problem is whenever i am trying to redirect to another action method the ajax post is executing the error block and whenever the action method is returning a string value it works fine. I don't want to use html form post. Below is my code:
function VerifyCreds() {
$.ajax({
type: "POST",
url: "/Login/Verify",
data: '{Username: "' + $("#txtUsername").val() + '",Password: "' + $("#txtPassword").val() + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
}
public ActionResult Verify(string Username, string Password)
{
string Response = "0";
EmployeeEntities ent = new EmployeeEntities();
var val = ent.VerifyUser(Username, Password);
Response = val.FirstOrDefault().ToString();
if (Response == "1")
{
return this.RedirectToAction("LandingPage");
}
return Content(Response);
}
public ActionResult LandingPage()
{
return View();
}
You are explicitly specifying json as the data type. that means, your ajax method expects the response from the server as a json string. The jQuery ajax method will use JSON.parse method to create a JavaScript object from this json string and pass it to the callback. When you do a redirect from server, it is not returning a 200 OK response back, but a 302 redirect response back and browser will usually makes a new call to the location header value of the response. You are getting the error callback of the ajax method because the server is returning some string which cannot be safely converted to a JavaScript object using JSON.parse. (My guess is that the response for the LandingPage call!. Check the network tab to see what response is coming)
If you absolutely want to handle this situation, you may better return a proper JSON structure in both the cases and inspect this json data at client side and do a redirect as needed.
I also suggest you to use the appropriate types. Use int instead of storing a number in a string variable.
public ActionResult Verify(string Username, string Password)
{
var ent = new EmployeeEntities();
var val = ent.VerifyUser(Username, Password);
var response = val.FirstOrDefault();
if (response == 1)
{
return Json(new { status="redirect", url = Url.Action("LandingPage")});
}
return Json(new { status="success", message = "Valid login" });
}
and in the success event of your ajax call, inspect this json data and based on the status property, do a redirect or show a message to the user.
success: function (response) {
if(response.status==="redirect")
{
window.location.href = response.url;
}
else
{
alert(response.message);
}
},
You can also totally remove dataType: "json", from your ajax call. jQuery will intelligently guess the type based on the response headers and use that. Since we are explicitly returning Json from our action method, the response Content-Type header value will be application/json

Is it possible for a Java controller to pass an attribute to a success ajax call?

As the title says, I want to pass a variable from a controller to a success ajax call function but is it possible? For example:
I have a Java class with a controller like this:
#RequestMapping(value = "checkFruit", method = RequestMethod.POST)
#ResponseBody
public ModelAndView checkFruit(HttpServletRequest request, String fruitInput) {
ModelAndView modelAndView = new ModelAndView();
if (fruitInput.equals("apple")) {
modelAndView.addObject("fruitType", 1); //This is what I want to pass to the success ajax call.
} else if (fruitInput.equals("orange") {
modelAndView.addObject("fruitType", 2); //This is what I want to pass to the success ajax call.
}
modelAndView.setViewName("fruitGarden");
return modelAndView;
}
And a jsp view with an ajax call like this:
$("#checkFruitBtn").click(function () {
var fruitInput = $("input[name=fruitInput]").val();
$.ajax({
type: 'POST',
url: 'checkFruit',
data: 'fruitInput=' + fruitInput,
success: function () {
var fruitType= ${fruitType}; //I want to get the attribule of that "fruitType" variable set in the controller. But this is where things went wrong.
if (fruitType == 1) {
alert("This is an apple.");
} else if (fruitType == 2) {
alert("This is an orange.");
}
window.location.href = "/someURL";
}
});
});
In the above example. When I click the button "checkFruitBtn", it will send an ajax call to the controller "checkFruit". And in this controller, I'll set a variable "fruitType" to send it to the success ajax call function. In this success ajax call function, I'll get the value of the "fruitType" variable to check it and show alert message according to its value... But, things aren't going as planned.
My question is, is there a possible way of getting the value of that "fruitType" variable? I've searched for a getting method but I still can't find one that fitted in my case. I'm terribly sorry if this question have been asked before.
Thanks in advance!
With annotation #ResponseBody, Springmvc converts the returned object to a response body by using an HttpMessageConverter.
ModelAndView usually involves command object and view name.
so you can use ModelAndView with a Jsp page , then use el to evaluate command object values. to use #ResponseBody, Springmvc only return strings.
$.ajax({
type: 'POST',
url: password_url,
data: '',
dataType: 'json',
success: function(response){
var g = response;
var x= g.fruitType; //Now you can do the operation based on the output.

ASP .NET MVC - Ajax POST action fail

I'm trying to do a simple action with some JavaScript code. I've got some items on a scheduler (DevExpress scheduler component). When I'm double clicking on an appointment (an item then), it should raise an JS function which is the case. My function should get the selected appointment id and pass it to Controller Action. Here is my JS code :
function DoubleClick() {
debugger;
var apt = GetSelectedAppointment(scheduler);
var aptid = apt.appointmentId;
$.ajax({
type: "POST",
url: "/Home/GetAppId",
data: { id: aptid },
dataType: 'json',
success: function () {
alert("ok");
},
error: function () {
alert("error");
}
});
}
And here is my C# code :
[HttpPost]
public JsonResult GetAppId(int id)
{
context = new SchedulingDataClassesDataContext();
DBAppointment app = (from a in context.DBAppointment where a.UniqueID == id select a).FirstOrDefault();
return Json(new {rep = app});
}
As you can see in my JS code, I'm not doing anything special in case of success. However, I never reach the success part. Plus, when I'm looking at the Chrome dev tool (F12), I'm getting that red error message.
POST http://localhost:25206/Home/GetAppId 500 (Internal Server Error)
Anything that I'm doing wrong?
Man, you need to force things as follows
return Json(new {rep = app},"text/json",JsonRequestBehavior.AllowGet);
In addition, mind your navigation properties (if any) in order to avoid circular reference
According to your error your problem somewhere in select your data from DB or creating anonymous object when you try to serialize it to Json. I rewrite your select to simplify it and not creating any anonymous objects when return it from Controller like this:
[HttpPost]
public JsonResult GetAppId(int id)
{
context = new SchedulingDataClassesDataContext();
DBAppointment app = context.DBAppointment.FirstOrDefault(x => x.UniqueID == id);
return Json(app);
}
Does it work like this?
Please remove the name of the property in ajax data and edit that property as below.
function DoubleClick() {
debugger;
var apt = GetSelectedAppointment(scheduler);
var aptid = apt.appointmentId;
$.ajax({
type: "POST",
url: "/Home/GetAppId",
data: aptid,
dataType: 'json',
success: function () {
alert("ok");
},
error: function () {
alert("error");
}
});
}
and edit your controller as follows
[HttpPost]
public JsonResult GetAppId([FromBody]int id)
{
//...
}
Please read this blog post which is a good read and allowed me to understand what's going on.
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
The original question that I asked
Simple post to Web Api
Try changing the last line of the method to:
return Json(new { rep = app }, JsonRequestBehavior.AllowGet);
You need to tell C# to allow the json to be returned to the client.

Categories

Resources