Below is my function (1st Code piece), when I run below function, it goes into to my code through my handler and in my code it throws exception (2nd Code piece), after exception is catched, it goes back to my handler and get's inside the catch area, and finally turns back to javascript success function, but error it doesn't run the error part.
BenefitOperations.performBenefitOperation = function(data) {
$.ajax({
type: "POST",
url: "BenefitOperation.axd",
data: JSON.stringify(data.BenefitOperationJson),
dataType: "json",
contentType: "application/json; charset=utf-8",
beforeSend: function() { PageMask.show(); },
success: function(response) {
if (response.Success == true)
performPostBack();
else
window.alert(Res.BenefitOperationFailure);
},
error: function(e, x, y) { window.alert(Res.BenefitOperationError + y); } }); }
This is my function
else
{
throw new ApplicationException(string.Format("Benefit operation type {0} for benefit type {1} is not registered", Enum.GetName(typeof(EmployeeBenefitData.BenefitOperationType), parameters.OperationTypeID), Enum.GetName(typeof(EmployeeBenefitData.BenefitTypeEnum), parameters.BenefitTypeID)));
}
this is my handler's catch
catch
{
jsonOutput = JsonConvert.SerializeObject(new
{
Success = false
});
}
finally
{
context.Response.Clear();
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.ContentType = "application/json";
context.Response.Write(jsonOutput);
}
The error callback of $.ajax() doesn't get called in your code because there is no error. error means there was an issue retrieving the response, eg. a 500 error from the server.
In your code you're catching the ApplicationException yourself and returning JSON. If you'd prefer to use the error handler, raise the exception and don't catch it in your C# code - however it should be noted your current code is a better method.
Rory is right,
just set HTTP 500 status code when you hit error / Exception or operation faild.
you can set HTTP 500 status code like...
context.Response.StatusCode = 200;
Related
I have an ASP.NET application sending data through AJAX to a handler withing my application. This works as it should when debugging locally, but as soon as I deploy the solution to the server, the handler only receives an empty string. I tried fiddling around with contentType and dataType, but without luck.
Here is my code so far.
aspx of the sending page, while "myData" is a simple string:
$.ajax({
type: "POST",
url: "handlers/changeRiskGroup.ashx",
data: myData,
// tried all those content/dataTypes without any luck
//contentType: "text/plain",
//dataType: "text",
//contentType: "application/json; charset=utf-8",
//dataType: "json",
error: function (xhr, status, error) {
console.log(xhr.responseText);
},
success: function (msg) {
console.log(msg);
}
});
.ashx.cs of the receiving handler:
public void ProcessRequest(HttpContext context) {
//string data = new StreamReader(context.Request.InputStream).ReadToEnd();
var data = String.Empty;
context.Request.InputStream.Position = 0;
using(var inputStream = new StreamReader(context.Request.InputStream)) {
data = inputStream.ReadToEnd();
}
if (data != "") {
// doing something with my data here.
// this is never reached while on the server, but works fine locally!
} else {
context.Response.Write("Please supply data to the risk group service!");
}
}
public bool IsReusable {
get {
return false;
}
}
}
The data variable in the .ashx.cs file is filled when debugging locally, but always "" on the server. I have no clue why.
var para={};
para.myData="abcd"
$.ajax({
type: "POST",
url: "handlers/changeRiskGroup.ashx",
data: para,
error: function (xhr, status, error) {
console.log(xhr.responseText);
},
success: function (msg) {
console.log(msg);
}
});
from server side
string myData=contect.Request.Form["myData"].toString();
Easy, just took me ~20 hours to figure out. Found the answer here: Web service returns "301 error moved permanently" in production environment
In short, I created a blank page within my project to ensure no plugins etc were interfering with the jQuery execution. Further, I created a very simple mask to submit certain data to the handler URL. Within this mask I varied different ways to POST data, when I tried implementing the POST as a [WebMethod] I finally got a clue, as the response was "301 moved permanently" from the WebMethod. Therefore I could start investigating and found out that my server was lowercasing the urls, obviously jQuery/HTTP does not like that.
I hope this post helps others struggling with similar problems.
I am calling a web service from my MVC view and wanting to use the jquery ajax error functionality on exception throw.
I am trying to throw a custom created exception from my MVC business layer into my presentation layer controller and rethrow it as a json response.
I can successfully throw my custom exception, the issue is it comes as a HTML view. I have seen ways to declare a custom error response, but I was hoping to be able to directly rethrow the exception as JSON.
Any ideas?
Javascript:
$.ajax({
type: "POST",
url: 'create',
data: "{userDetails:" + JSON.stringify(details) + "}",
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.d;
redirectSuccess();
},
error: function(err) {
//display thrown exception here
}
});
CS
public JsonResult create(MyModel.New details)
{
try
{
Library.insert(details);
return Json(true);
}
catch (Exception ex)
{
throw;
}
}
Thanks in advance for any help!
I ended up working out a solution appropriate.
For anyone wanting a similar answer to the question I asked, what i did was declare a custom filter. The main parts of this is setting the filter result to return as JSON, but even then it would return as success in the jquery ajax call because it returned a status of 200 which jquery ajax reads as success.
Jquery ajax reads any status outside of 200 as an error so as you can see I changed the status code to a custom number that i created and will document and therefore the jquery ajax sees an error and throws it to ajax error.
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.HttpContext.Response.StatusCode = 11001;
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
To reference the current filter, you just add the error handler attribute to the function as shown in the first line below:
[MyErrorHandler]
public JsonResult create(MyModel.New details)
{
try
{
Library.insert(details);
return Json(true);
}
catch (Exception ex)
{
return Json(ex.Message);
}
}
I don't think it works the way you think it does you need to pass exception to frontend as responce.
public JsonResult create(MyModel.New details)
{
try
{
Library.insert(details);
return Json(true);
}
catch (Exception ex)
{
return Json(ex.Message);
}
}
And then handle it with JS as success.
$.ajax({
type: "POST",
url: 'create',
data: "{userDetails:" + JSON.stringify(details) + "}",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.Message)
{
//display error
}else{
data = data.d;
redirectSuccess();}
},
error: function(err) {
//display thrown exception here
}
});
I am getting this error "There was an error processing the request" in the UAT environment. In my local, the code seems to be working fine.
This line Utility.WriteLogEvent("TestService", strMessage); is writing directly to db. Either way if this line fails or not, I should still be able to recieve a message coming from the server since it is properly handled.
But since I don't receive any response from the server, that means my webmethod is not reachable.
Given that the code below works, is there anything that I need to set in the web.config to make this work? Or anywhere I can start inspecting on the IIS that could give me some clues?
Thanks.
$('#lnkTest').click(function () {
alert('Click event is firing!');
$.ajax({
type: "POST",
url: "/_layouts/ServiceForm.aspx/TestService",
data: "{}",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (response) {
if (response.d && response.d.length > 0) {
alert(response.d);
}
},
error: function (xhr, err) {
alert('responseText:' + xhr.responseText);
}
});
});
Here is my c# web method
[WebMethod]
public static string TestService()
{
string strMessage = string.Empty;
try
{
strMessage = "The service is running.";
Utility.WriteLogEvent("TestService", strMessage);
}
catch (Exception ex)
{
strMessage = "TestService fail.";
}
return strMessage;
}
For others who might come across the same error while calling a WebMethod with parameters.
Ensure that none of the arguments are empty as that also throws the same error without a proper reason. Provide a solution to prevent empty arguments from being passed to the Method on the client side. Perhaps an if statement.
I have resolved the issue. This is due to a dll deployed in the application server and it was blocked by the installed antivirus.
I'm wondering how should look the correct way of dealing with data transmission and handling errors using latest jquery ajax requests with http compatible approach.
I've noticed, that when unhandled exception occurs at server side, and I did not specify the data type I'm expecting in http protocol, the success method invokes and the client receives 200 OK response, as if nothing wrong happend:
$.ajax({
url: action,
type: 'POST',
data: jsondata,
success: function (data, textStatus, xhr) {
// i'm here now
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
If I specify type, that I'm expecting for exaple json, an ajax error function invokes. It's because stack trace is not serialized by default to json, so parsing will fail:
$.ajax({
url: action,
type: 'POST',
dataType: 'json',
data: jsondata,
contentType: 'application/json; charset=utf-8',
success: function (data, textStatus, xhr) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// but now I'm here
}
});
Now it's also 200 OK, but an error (not success) is invoked.
What is the better way to cope with exception handling. Should I specify the type, which is more RESTFull in my opinion, or just let it be unspecified, and always jump into success ?
Should I always wrap ajax method at the server side in try{}catch(){} block, and pass error of appropriate type, the client asks me to return ?
[HttpPost]
public NJsonResult Execute()
{
try
{
// do some logic if you do not mind
if (success)
{
return new NJsonResult(new {status = "success"});
}
return new NJsonResult(new { status = "error" });
}
catch(Exception e)
{
return new NJsonResult(new { status = "error" });
}
}
$.ajax({
type: 'POST',
url: action,
dataType: 'json',
data: jsondata,
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.status == "success") {
}
else (data.status == "error") {
}
}
Mabye should I always care of predictable errors and don't care about exceptions, and did not specify any type ?
[HttpPost]
public NJsonResult Execute()
{
// do some logic if you do not mind
if (success)
{
return new NJsonResult(new {status = "success"});
}
return new NJsonResult(new { status = "error" });
}
$.ajax({
type: 'POST',
url: action,
data: data,
success: function (data) {
if (data.status == "success") {
}
else {
// handle even exceptions, because content-type in not specified
}
}
});
Where is the place for error function and correct http status codes (not always 200 OK)
Now, I've implemented a global hook for intercepting unhandled exceptions:
$(document).ready(function () {
$.ajaxSetup({
error: function (XMLHttpRequest, textStatus, errorThrown) {
// handle it if you dare
}
});
});
and always specify the content-type and accept headers, using contentType and dataType ajax properties. I do not use try{}catch{} block - I don't care about logic abnormal behavior. I just log it in Global.asax and pass it further to the response.
So, as in the first lines of this question, what is the best approach ? Any other ideas ?
I am developing an app in asp.net in which I have jquery code in my asp page
var strdata = {
problemID: $("#problemID").val(),
commentText: $("#_1").val(),
empID: $("#empID").val(),
agree: 0,
disagree: 0
};
$.ajax({
type: "POST",
url: "<%= Url.Action("PostComment", "Discussion") %>",
data: strdata,
dataType: "JSON",
success: function (msg) {
if ( msg == 1)
alert("Success" + msg );
}
});
and my controller has code
public bool PostComment(string problemID, string commentText, string empID, string agree, string disagree)
{
return _discussionRepository.postComment(Convert.ToInt32(problemID), commentText, Convert.ToInt32(empID), Convert.ToInt32(agree),Convert.ToInt32( disagree));
}
and model has code
public bool postComment(int problemID, string commentText, int empID, int agree, int disagree)
{
bool result = false;
Comment c = new Comment();
c.ProblemID = problemID;
c.CommentText = commentText;
c.EmpID = empID;
c.Agree = agree;
c.DisAgree = disagree;
_objectModel.Comments.InsertOnSubmit(c);
try
{
_objectModel.SubmitChanges();
result = true;
}
catch (Exception ex)
{
}
return result;
}
Data is saving in database through ajax and jquery but the success message is not showing
If the alert is not running with or without the condition that means the datatype being returned is not the datatype the $.ajax function is expecting.
2 ways to get to the bottom of it:
First open up chrome or firebug and check out the network traffic. If you are getting the result back (the request is being made and the content looks accurate) then your data type is definitely the cause. Try changing the datatype in the request.
Next you could try adding functions other than just success. There is also error, status codes (404,500 etc), beforeSend, etc check the docs.
There are other ways as well :). Fiddler might help too.
To get the result of your AJAX request use the following code in your success handler:
success: function (msg) {
if ( msg.d === true) {
alert("Success" + msg.d );
}
}
You have to access the result via the "d" property.
To get the error message use the following error handler:
error: function(jqXHR, textStatus, errorThrown){
alert(errorThrown);
}
i think the result returned in 'msg' isnt the number 1. maybe msg == true ?