Ajax always executes error function on success with Asp.Net HttpResponseMessage - javascript

When I send my Ajax request I can see that the returned status code is 200 which means everything worked fine. However, it always executes the error function instead of the success function.
Web Api
public HttpResponseMessage ChangeModus(Artikel Artikel)
{
return Request.CreateResponse(HttpStatusCode.OK);
}
JavaScript
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: "/Api/Artikel/ChangeModus",
data: JSON.stringify(Artikel),
success: OnSaveSuccess,
error: OnSaveError
});
function OnSaveSuccess(response) {
alert("Success")
}
function OnSaveError(response) {
alert("Ein Fehler ist aufgetreten");
}
Am I doing something wrong or why does it always execute the Error function?

The error is occurring because although you have a 200 (OK) response, the response does not include a response body. You should either send content with the response, or use HttpStatusCode.NoContent (204) instead.

Like Jakob said, the problem occurs because there has to be a response body otherwise javascript will execute the error function.
Choose one of the following options:
public HttpResponseMessage ChangeModus(Artikel Artikel)
{
return Request.CreateResponse(HttpStatusCode.OK, "Success");
}
Or:
public HttpResponseMessage ChangeModus(Artikel Artikel)
{
return Request.CreateResponse(HttpStatusCode.NoContent);
}

Related

TypeScript : Ajax call call always calling Error rather than success on success

In typescript I have a DataAccess Class so that all Ajax calls are routed through a single object to save repetition of code in a lot of places within my application.
In using this approach I have needed to use call backs to get the response back to the calling class so that the success and error can be handled accordingly.
This is the typescript
ajaxCall(retVal, retError) {
$.ajax({
type: this.callType,
data: this.dataObject,
dataType: this.dataType,
url: this.url,
contentType: this.contentType,
traditional: this.traditional,
async: this._async,
error: retError,
success: retVal
});
}
This is the compiled Javascript
AjaxDataAccessLayer.prototype.ajaxCall = function (retVal, retError) {
$.ajax({
type: this.callType,
data: this.dataObject,
dataType: this.dataType,
url: this.url,
contentType: this.contentType,
traditional: this.traditional,
async: this._async,
error: retError,
success: retVal
});
};
return AjaxDataAccessLayer;
This calls through to the ASP.Net MVC controllers perfectly fine, however the problem that I have is regardless of Success or Error the call back is always retError.
This is the calling Typescript
var _this = this;
var dataAccess = new DataAccess.AjaxDataAccessLayer(Fe.Upsm.Enums.AjaxCallType.Post,
Fe.Upsm.Enums.AjaxDataType.json,
"../../PrintQueue/DeletePrintQueueItems",
jsonObj);
dataAccess.ajaxCall(data => {
// success
new Fe.Upsm.Head().showGlobalNotification("Selected Items Deleted");
_this.refreshPrintQueueGrid();
(window as any).parent.refreshOperatorPrintQueueCount();
}, xhr => {
// failure
alert("An Error Occurred. Failed to update Note");
});
When stepping through and looking at this the Status is OK and the response is 200.
So, Problem (as mentioned above) always calling xhr \ retError regardless of success.
Question: How do I get it to go into the right call back?
In your error handler, you were not passing all the parameters, so you are only checking whether the request finished successfully. However, there can be errors after that, like when the response is processed. You can handle errors betters like this:
dataAccess.ajaxCall(data => {
// success
new Fe.Upsm.Head().showGlobalNotification("Selected Items Deleted");
_this.refreshPrintQueueGrid();
(window as any).parent.refreshOperatorPrintQueueCount();
}, (xhr, errorText, errorThrown => {
// failure
console.log(xhr, errorTest, errorThrown);
alert("An Error Occurred. Failed to update Note");
});
Based on the discoveries using this method, the error is that your controllers are returning empty responses, so you're getting an exception when jQuery tries to parse them, because an empty string is not valid JSON.

AJAX error is returned as Success

AJAX error is being returned as Success. How to return JSON error from ASP.NET MVC? Could you tell me what I'm doing wrong? Thank you.
[HttpPost]
public JsonResult Register(int EventID)
{
try
{
// code
return Json(new { success = true, message = "Thank you for registering!" });
}
catch (Exception ex)
{
return Json(new { success = false, message = ex.Message });
}
}
$.ajax({
url: "#Url.Action("Register", "Home")",
type: "post",
dataType: "json",
contentType: "application/json",
data: JSON.stringify(postData),
success: function(data) {
},
error: function (data) {
}
});
The error function gets executed only when the HTTP Response Code is not HTTP 200 Ready. You handle the error in the server-side and return proper response, which will be picked up by success function in the AJAX call. Instead, use the status variable in your JSON and handle it on the client side:
success: function(data) {
if (typeof data == "string")
data = JSON.parse(data);
if (data.success) {
// Code if success.
} else {
// Code if error.
}
},
From the docs (scroll down to the error section):
A function to be called if the request fails. The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror". When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error." As of jQuery 1.5, the error setting can accept an array of functions. Each function will be called in turn. Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event.
The Ajax error method is hit only when you get a Yellow Screen Error in the server side. In your scenario you are handling the error using try catch and returning a valid response. So this is not considered as a error but a valid response. Remove your try catch so that Ajax will pick up the error event, else if you want to show the actual error message from server then you can use the success property to decide if the response was a success or a error , its similar to what Praveen has already posted in his answer.
success: function(data) {
if (data.success) { //as you are passing true/false from server side.
// Code if success.
} else {
// Code if error.
}
},

ASP.NET/WebAPI: $.ajax has 404 and $.getJSON has Uncaught RangeError: Maximum call stack size exceeded

I'm working on a ASP.NET web API with a C# project that I try to call from JavaScript.
Here is my JavaScript:
function LoadGraph() {
var file = document.getElementById("file-datas");
if ('files' in file)
{
if (file.files.length == 0) {
Console.log("Empty file");
} else {
var text = file.files;
/*$.ajax({
url: "api/Graph",
type: "POST",
dataType: "json",
processData: false,
contentType: false,
data: $(text).serialize(),
cache: false,
success: function (data) {
console.log(data);
}
})*/
//$.getJSON('api/Graph', file, function (data) { console.log(data) });
}
}
And here is my Controller:
[Authorize]
[RoutePrefix("api/Graph")]
public class GraphController : ApiController
{
// POST: api/Graph
[HttpPost]
[Route("All", Name = "LoadGraph")]
public IHttpActionResult LoadGraph(string text)
{
RecursiveGraph result = test.SecondMethodFruchterman(text);
return Ok(result.name);
}
}
As you see I tried two methods in my JavaScript:
The first one with $.ajax makes POST http://localhost:53497/Home/api/Graph 404 (Not Found).
The second one with $.getJSON makes Uncaught RangeError: Maximum call stack size exceeded.
result.name is a string but I want to transfer result itself after solving these problems and getting something that works.
I don't know which one of the two method is better to use.
I don't know why I get a 404 error on $.ajax and no on $.getJSON.
And I don't know why I get this Max call stack error since it seems to appear when recursive functions are called and it's not the case here.
The first problem is that the resolved URL is POST http://localhost:53497/Home/api/Graph 404 (Not Found) which is wrong since your URL is actually supposed to be http://localhost:53497/api/Graph. To fix, prepend your AJAX urls with a /.
The second problem is likely the server error being returned as text to your web client. It is probably due to your recursion never terminating. I can't see that code in detail, but RecursiveGraph result tips me off. I'd bet on your recursive method never terminating, which would definitely max out the callstack.
I think you shall change your ajax call to this:
$.ajax({
url: '#Url.Action("LoadGraph", "Graph")',
type: "POST",
traditional: true,
data: {
text: $(text).serialize()
},
cache: false,
success: function (data) {
console.log(data);
}
})
You get the 404 (not found error code) because your ajax post url api/Graph is just your referring to your controller
Why did you even change your controller RoutePrefix to "api/Graph"? Is there a special reason for doing this?
Here the corrected code
//[Authorize]
[RoutePrefix("api/Graph")]
public class GraphController : ApiController
{
// POST: api/Graph
[Route("LoadGraph", Name = "LoadGraph")]
public IHttpActionResult LoadGraph([FromBody] string text)
{
RecursiveGraph result = test.SecondMethodFruchterman(text);
return Ok(result);
}
}
I need to add [FromBody] because string is not a model.

Calling a C# method from JavaScript

I want to to call a method GetAccount from my controller AccountController.cs, in my JavaScript factory LoginFactory.js. Something like this:
AccountController.cs:
public Account GetAccount(string userName)
{ ... }
LoginFactory.js:
if(x>y) {
var account = <%AccountController.GetAccount(someParam);%>
}
I've tried using [WebMethod] and Ajax, but I can't get it to work: I get a 404 response.
Assuming your GetAccount method can be reached at /Account/GetAccount when your application runs, you could use the following:
$.ajax({
type: 'GET',
url: '/Account/GetAccount',
data: { 'username' : 'a-username' },
dataType: 'json',
success: function(jsonData) {
alert(jsonData);
},
error: function() {
alert('error');
}
});
Note - this is dependant on jQuery.
This causes the browser to make a request to /Account/GetAccount as if you had done so by entering the URL in the URL bar, but of course, captures the returned json for use in your client side (javascript) script.
If this returns a 404, it would be worth checking your routing.

No response status in ajax call not sure why

I have the following ajax call which is made to my spring mvc app..
alert("ready");
$.ajax({
type: "GET",
url: document.location.toString()+ "/dashboard",
success: function(response) {
alert(response);
alert(response.status);
$("#frameBody").contents().find("html").html(response);
// we have the response
if(response.status == "SUCCESS") {
alert(response);
// do nothing..
// check for no content... if there is content... replace iframe
// $("#frameBody").attr('src', jsonObj.url);
// $(""#frameBody").contents().find("html").html(response);
}
else {
// do nothing yet
}
},
error: function(e){
$("#errors").attr("style", "display:inline")
$('#errors').html(e.responseText);
window.setTimeout("fadeErrorsDiv();", 5000);
}
});
my mvc controller:
#RequestMapping(value = "/dashboard", method = RequestMethod.GET)
#ResponseStatus(value=HttpStatus.OK)
public String dashboard(Model model, HttpServletRequest req) {
int i = 0;
return "login";
}
My question is that i cant see why this is not producing the response status that i expect?... it gives me undefined when i check for response.status in javascript?.. any idea why
See JQuery .get docs. It would seem your "response" object inside your success callback will actually be "login". Therefore you're infact trying to do "login".status.

Categories

Resources