passing multiple object to controller using ajax in ASP.NET MVC - javascript

I work on an ASP.NET MVC project.
I have to pass two parameters to an action in my controller. the first is a serializable object, and the second one is an integer.
First time I tried to pass only one parameter, the serializable object. There is no problem, but when I add the second parameter, the serializable object doesn't delivered (null value), but the integer parameter delivered successfully.
this is my action look like :
[HttpPost]
public bool MyAction(MySerializableObject myData, int intParameter)
{..}
and this is how I try to pass the parameters :
$('#submit-button').click(function () {
var formData = $("#MyForm").serialize();
var posturl = '/MyController/MyAction';
var retUrl = '/MyCOntroller/SomeWhere';
...
$.post(posturl, { myData: formData, intParameter: '5005' }, function (result) {
if (result == 'True') {
location.href = retUrl;
}
else {
alert('failed');
}
});
});
Anyone can explain about it ? how can it happens and how to solve the problem ?
thanks.

this may be a bit of a longshot but have you tried swapping the order of the parameters around (IE public bool MyAction(int intParameter, MySerializableObject myData) The reason im asking is that it may be that your client side serialize isnt working quite right.
If not your best bet is to take a look at whats actally getting posted to the server. Open up firebugs net tab or similar in webkit and take a look at whats actually going back to the server.

You could use the following plugin (serializeObject) instead of .serialize:
var formData = $('#MyForm').serializeObject();
// add some data to the request that was not present in the form
formData['intParameter'] = 5005;
var posturl = '/MyController/MyAction';
var retUrl = '/MyCOntroller/SomeWhere';
...
$.post(posturl, formData, function (result) {
if (result == 'True') {
location.href = retUrl;
}
else {
alert('failed');
}
});

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;

Pasing Javascript result to View

I got a Question, I'm really new in working with Asp.net.
I got a Javascript where I woult like to pass Data to my Controller.
<script type="text/javascript">
$("#SearchButton").on("click", function () {
var $sucheMoped = [];
$("#tab_logic tbody tr")
.each(function () {
var $Item = $(this);
var suchfeld = $Item.find("td > input[name='Suchfeld']").val();
var schluessel = $Item.find("td > select[name='Suchschluessel'] > option:selected").val();
alert(suchfeld + "&&&" + schluessel);
$sucheMoped.push({
Suchfeld: suchfeld,
Suchschluesseltyp: schluessel
});
});
window.open('#Url.Action("MainView","MainView")?SuchObject='+$sucheMoped);
})
</script>
I just would like to pass the "sucheMoped" from my javaScript to my Controller.
My Controller is just expecting a IEnumarable of Objects with Properties Suchfeld and Suchschluesseltyp.
Anyone an idea?
Thanks Guys.
First of all, you need to change the way you invoke the controller action. You should stringify the array using the JSON.stringify() method.
So, this should look like this:
window.open('#Url.Action("MainView","MainView")?SuchObject='+JSON.stringify($sucheMoped));
Then, you need to create a custom model binder to bind your array with the action parameter. This is a simple array model binder for demonstration purposes only, it doesn't take into account failures or whatever, but it works in this scenario, passing the correct data, so please modify it to fit your needs.
public class ArrayModelBinder: DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var rawArray = controllerContext.HttpContext.Request.QueryString["SuchObject"];
var array = JsonConvert.DeserializeObject<IEnumerable<MyObject>>(rawArray);
return array;
}
}
What I do here, is to get the query string submitted through the URL, convert it with JsonConvert.Deserialize<T> method and return it.
You simply need to decorate your parameter in the controller's action with the custom model binder, like this:
[HttpGet]
public ActionResult Search([ModelBinder(typeof(ArrayModelBinder))]IEnumerable<MyObject> SuchObject)
{
return View(SuchObject);
}
Edit
window.open is useful if you want to open a new browser window. You could use it to open a new tab as well.
In order to navigate to another location without opening a new tab or window, use the window.location property like the following:
window.location = '#Url.Action("Search", "Home")?SuchObject=' + JSON.stringify(array);
If you use the jQuery.ajax method, you can pass complex objects as data parameter.
$.ajax({
url: '#Url.Action("MainView", "MainView")',
type: 'GET',
data: { 'SuchObject': $sucheMoped },
success: function (htmlContent) {
// write content to new window (from http://stackoverflow.com/a/23379892/1450855)
var w = window.open('about:blank', 'windowname');
w.document.write(htmlContent);
w.document.close();
}
});
You can use jquery library $.getScript to call the action method in your controller and the return javascriptResult type in your action.
$.getScript("Home","Display")
// Home Controller
private JavaScriptResult Display()
{
string message = "alert('Hello World');";
return new JavaScriptResult { Script = message };
}

Ajax call don't receive html content from MVC Action

This is my action:
[HttpGet]
public virtual ActionResult DesignItemsList(int dealId, string sort)
{
return View(MVC.Designer.Views._DesignItems, _designerService.GetDesignItems(dealId, sort));
}
The GetDesignItems() method is working correctly.
$(document).ready(function() {
$('.product__filtr__form__select').change(function(e) {
var sort = $(this).val();
var urlFilter = $('#url-filterPanel-hidden-field').val();
var dealId = $('#dealId-hidden-field').val();
var urlItems = $('#url-items-hidden-field').val();
$.ajax({
type: "GET",
data: {
dealId: dealId,
sort: sort
},
url: urlItems,
success: function (result) {
console.log(result);
$('#Product-Items-Container').html(result);
}
});
});
});
Request is working too, but I don't receive the response and get only 500 code.
500 error code means, Internal server error. Your action method failed to process thie request you sent.
Since it is a GET action method, You may add the query string parameters to the url.
var sort = $(this).val();
var dealId = $('#dealId-hidden-field').val();
var urlItems = $('#url-items-hidden-field').val();
urlItems = urlItems+"?dealId="+dealId+"&sort"+sort;
//Let's write to console to verify the url is correct.
console.log(urlItems);
$.get(urlItems,function(res){
console.log('result from server',res);
$('#Product-Items-Container').html(res);
});
Try to replace the view name inside your controller:
return View("YourControllerView", _designerService.GetDesignItems(dealId, sort));
Because I was tested your ajax request and find out that it works fine.
And pay attention to view location. This view must be located inside the directory with the same name as your controller or inside the shared dictory

Sending a string to ActionResult using ajax

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.

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