jQuery Ajax failing to call to MVC 4 Controller method - javascript

I'm attempting to use jQuery in order to fire off an Ajax call after clicking a certain button. I've read several examples of the syntax and issues that may be encountered, but have failed to find a working solution for my cause. Here's the code.
Controller Method: (HomeController.cs)
[HttpPost]
public JsonResult ChangeCompany(string companyCode)
{
return Json(new { result = companyCode }, JsonRequestBehavior.AllowGet);
}
jQuery Code:
function changeCompany(company) {
$.ajax({
url: '#Url.Action("ChangeCompany", "Home")',
type: 'POST',
data: JSON.stringify({ companyCode: company }),
success: function (data) {
alert("Company: " + data);
},
error: function (req, status, error) {
alert("R: " + req + " S: " + status + " E: " + error);
}
});
}
And finally, I'm calling this function with:
$('.companyButton').click(function () {
compCode = $(this).text();
debug("Click event --> " + $(this).text());
changeCompany(compCode);
});
My debug message displays properly, and the Ajax call constantly fails with the following alert: R: [object Object] S: error E: Not Found
I'm not entirely sure what to make of that.
I know there are several questions on this topic, but none of them seem to resolve my issue and I'm honestly not sure what's wrong with these code blocks. Any insight would be appreciated.
EDIT:
In case it's worth noting, this is for a mobile device. Testing on Windows 8 Phone Emulator (Internet Explorer), alongside jQuery Mobile. Not sure if that affects Ajax at all
EDIT 2:
After taking a look at the raw network call, it seems that 'Url.Action("ChangeCompany", "Home")' is not being converted into the proper URL and is instead being called directly as if it were raw URL text. Is this due to an outdated jQuery, or some other factor?

Ok with your EDIT2 it seems you are using url: '#Url.Action("ChangeCompany", "Home")', in a separate JavaScript file. you can only write the razor code inside the .cshtml file and it is not working inside the .js files

You are missing some important parameters in your AJAX call. Change your AJAX call as below:
function changeCompany(company) {
$.ajax({
url: '#Url.Action("ChangeCompany", "Home")',
type: 'POST',
data: JSON.stringify({ companyCode: company }),
success: function (data) {
alert("Company: " + data);
},
error: function (req, status, error) {
alert("R: " + req + " S: " + status + " E: " + error);
}
});}
You can then annotate your controller method with [HttpPost] attribute as below;
[HttpPost]
public JsonResult ChangeCompany(string companyCode)
{
return Json(new { result = companyCode }, JsonRequestBehavior.AllowGet);
}

Note that your action is not returning companyCode directly. You're assigning it to Json result property therefore
In your success function to display result you need to have:
success: function (data)
{
alert("Company: " + data.result);
}
Also this: E: Not Found tells me that you may have some routing issues. If you set a break point inside of your ChangeCompany Action, is it being hit ?

Related

How to have NanoHTTPD respond to AJAX

I'm attempting to get NanoHTTPD (on an android device) to respond to AJAX requests in a way that the requesting javascript can interpret the response.
I've implemented the NanoHTTPD serve method:
public NanoHTTPD.Response serve(String uri, NanoHTTPD.Method method,
Map<String, String> header,
Map<String, String> parameters,
Map<String, String> files) {
String msg = "Hello, you have connected.";
return newFixedLengthResponse( msg );
}
And if I connect from the local webbrowser to "http://127.0.0.1:8080" it loads a page with the source:
<html>
<head></head>
<body>Hello, you have connected.</body>
</html>
So far so good, although I'm not sure where the html formatting is introduced.
But what I am stuck on is if I use AJAX from javascript to try to pass data:
$.ajax({
url: 'http://127.0.0.1:8080',
type: 'POST',
data:{ printData: dataToPrint },
success: function(d){
alert('success');
},
error: function (jqXHR, textStatus) {
alert("failed, jqXHR: " + jqXHR.responseText + " " + jQuery.parseJSON(jqXHR.responseText) + " textStatus: " + textStatus);
}
})
(This is just one example, I've tried success/fail/done/error methods, I've tried specifying the datatype, I've tried different parameters in the return functions, none of it works). When this javascript is run the NanoHTTPD server receives the printData just fine, but when it sends it response it is only ever the error/fail method that is triggered and the method parameters never contain anything - I cannot set the status or the return message or anything.
I've tried different returns from the Serve method including:
String mime_type = NanoHTTPD.MIME_PLAINTEXT;
String msg = "{\"status\":\"1\",\"responseText\":\"this is the response\"}";
InputStream testReply = new ByteArrayInputStream(msg.getBytes(StandardCharsets.UTF_8));
// return newFixedLengthResponse(NanoHTTPD.Response.Status.OK, "", msg);
// return new NanoHTTPD.Response( NanoHTTPD.Response.Status.OK, mime_type, testReply);
// return NanoHTTPD.newFixedLengthResponse( NanoHTTPD.Response.Status.OK, mime_type, msg);
// return NanoHTTPD.newFixedLengthResponse(msg);
None of these work.
I also tried this javascript:
$.get("http://127.0.0.1:8080", function( my_var ) {
console.log(my_var);
});
If this is run my breakpoint on NanoHTTPD is triggered, but the javascript method is not triggered at all.
I think you need to add these headers in your server response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400

Ajax call not reaching controller method

Yes, there are a whole bunch of posts with similar questions. I've tried to follow the answers in them, but my ajax call still isn't reaching the controller method.
controller (SalesController.cs):
[HttpGet]
public JsonResult fillVarietiesSelect(int species_id)
{
String[] alist = {"a","b","c"};
return Json(alist, JsonRequestBehavior.AllowGet);
}
javascript:
$('#species-select').on('change', function () {
var species_id = $('#species-select').val();
console.log("species id selected " + species_id);
alert("species id selected " + species_id);
$('#variety-select').empty();
$.ajax({
type: 'GET',
url: '#Url.Action("fillVarietiesSelect", "Sales")',
data: {species_id : species_id},
success: function (result) {
alert(result);
}
});
});
The on change event is firing, and the alert pops up with the correct data. I have a breakpoint set at the controller method, but execution doesn't seem to get there.
try doing exactly like following
Controller:
[HttpGet]
public ActionResult receive2(string p)
{
ViewBag.name = p;
List<string> lst = new List<string>() { p };
return Json(lst,JsonRequestBehavior.AllowGet);
}
Client side
$.ajax({
type: "GET",
url: "Main/receive2", // the method we are calling
contentType: "application/json; charset=utf-8",
data: { "p": $("#txtname").val() },
dataType:"json",
success: function (result) {
alert("yes");
alert('Yay! It worked!tim' + result);
window.location = "http://google.com";
// Or if you are returning something
},
error: function (result) {
alert('Oh no aa :(' + result[0]);
}
});
I have checked it's working
I had the same issue, changing the parameter from int to string resolved the problem.
On the server side I had,
public string RemoveByDocumentID(int DocumentID)
changing that to
public string RemoveByDocumentID(string DocumentID)
resolved the issue.
On the same context, I have another method in the same name (overloaded method). Which was also contributing to the issue, so I made the method name unique.
Your 404 error is telling you that #Url.Action is not being parsed by the view engine. The # is Razor syntax, so for this to work you need to be using a .cshtml extension for C# views or .vbhtml for VB views and be using MVC 3 or above.

display a javascript function

I am creating an API and I want to show a code example in javascript that you can use to invoke the API.
I write a test function in javascript. I would like to be able to execute AND display the code for the javascript function(s) but I would rather only have one copy of the code to make maintenance easier.
Example, I have the following code:
function doauth_test(apikey,username,userpass)
{
$.ajax({
url: "/api/v1.2/user.php/doauth/" + username + "/" + userpass + "?apikey=" + apikey,
type: "GET",
success: function(data,textStatus,xhr) {
var obj = JSON.parse(data);
var authkey = obj.authkey; //store this somewhere for subsequent use
var user_id = obj.user_id; //store this somewhere for subsequent use
},
error: function(xhr, ajaxOptions, thrownError) {
alert("ERROR! Status code: " + xhr.status + " Response Text: " + xhr.responseText);
}
});
}
I want this code to be something I can EXECUTE and I want it to display the code in a DIV in my documentation example. But I do not want to (ideally) have two copies of this code.
You can call toString() on a function to get its source code.
Alternatively, you can use the DOM to get the text of the <script> tag.
Just use toString method for your function and it will return your function definition as a string.
alert(doauth_test.toString());
Hope it helps!

JQuery Ajax POST no longer hits ServerSide asp.net Method after adding parameters

Before adding any parameters I had this POST method hitting my serverside code whenever a user would set focus from one control to another. This was good but i need to pass data of the id and value. These values are being populated from what gather in my failure growl.
The issue is that I don't exactly know why it will no longer hit my serverside routine. I did look around stackoverflow a good deal for some help, i did clean up a few things but I couldnt quite pinpoint exactly where my issue is.
$(document).ready(function () {
var id;
var value;
$(".tpControl").blur(function () {
id = this.id;
value = $(this).val();
var postdata = { identifier: id, controltext: value };
$.ajax({
type: "POST",
url: "TimePoints.aspx/ClientSideSave",
contentType: "application/json; charset=utf-8",
data: postdata,
dataType: "json",
success: function (msg) {
if (msg.hasOwnProperty("d")) {
OnSuccess(msg.d);
} else {
OnSuccess(msg);
}
},
error: OnFailure
});
});
function OnSuccess(result) {
$.growlUI('AutoSave Successful');
}
function OnFailure(result) {
$.growlUI("ID: " + id, "Answer: " + value);
}
});
My Server side is pretty simple
[WebMethod]
public static void ClientSideSave(string identifier, string controltext)
{
//Bunch of code, shouldn't affect anything.
}
Thank you in advance. Any help would be great, im pretty new to the world of Jquery and Ajax.
You were close, but remember you are posting JSON, not form value collections. This means JSON strings are quoted during transport and in your example, will be quoted on the backend, probably not what you really want:
var postdata = "{ 'identifier': 'id', 'controltext': 'value' }";
3 mistakes to avoid when using jQuery with ASP.NET AJAX
If you want use JSON(JavaScript Object Notation) the right way, then you should follow this example:
Using complex types to make calling services less… complex

Save temporary Ajax parameters in jQuery

I am developing a heavily scripted Web application and am now doing some Error handling. But to do that, I need a way to access the AJAX parameters that were given to jQuery for that specific AJAX Request. I haven't found anything on it at jquery.com so I am asking you folks if you have any idea how to accomplish that.
Here is an example of how I want to do that codewise:
function add_recording(filename) {
updateCounter('addRecording','up');
jQuery.ajax({
url: '/cgi-bin/apps/ajax/Storyboard',
type: 'POST',
dataType: 'json',
data: {
sid: sid,
story: story,
screen_id: screen_id,
mode: 'add_record',
file_name: filename
},
success: function(json) {
updateCounter('addRecording','down');
id = json[0].id;
create_record(id, 1, 1, json);
},
error: function() {
updateCounter('addRecording','error',hereBeData);
}
})
}
hereBeData would be the needed data (like the url, type, dataType and the actual data).
updateCounter is a function which updates the Status Area with new info. It's also the area where the User is notified of an Error and where a Dismiss and Retry Button would be generated, based on the Info that was gathered in hereBeData.
Regardless of calling complete() success() or error() - this will equal the object passed to $.ajax() although the values for URL and data will not always be exactly the same - it will convert paramerters and edit the object around a bit. You can add a custom key to the object to remember your stuff though:
$.ajax({
url: '/',
data: {test:'test'},
// we make a little 'extra copy' here in case we need it later in an event
remember: {url:'/', data:{test:'test'}},
error: function() {
alert(this.remember.data.test + ': error');
},
success: function() {
alert(this.remember.data.test + ': success');
},
complete: function() {
alert(this.remember.data.url + ': complete');
}
});
Of course - since you are setting this data originally from some source - you could rely on the variable scoping to keep it around for you:
$("someelement").click(function() {
var theURL = $(this).attr('href');
var theData = { text: $(this).text(); }
$.ajax({
url: theUrl,
data: theData,
error: function() {
alert('There was an error loading '+theURL);
}
});
// but look out for situations like this:
theURL = 'something else';
});
Check out what parameters you can get in the callback for error.
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
You can use the ajax complete event which passes you the ajaxOptions that were used for the request. The complete fires for both a successful and failed request.
complete : function (event, XMLHttpRequest, ajaxOptions) {
//store ajaxOptions here
//1 way is to use the .data on the body for example
$('body').data('myLastAjaxRequest', ajaxOptions);
}
You can then retireve the options using
var ajaxOptions = $('body').data('myLastAjaxRequest');

Categories