2

I have a project in MVC4 with C#. In this project, one of my controllers has a method to be called by an Ajax function:

[HttpPost]
public string EditPackage(int id, string newPkgName)
{
    try{
        //do logic here
        return "OK";
    }catch(Exception exc){
        return "An error occurred, please try later! " + exc.Message;
    }
}

This method is called by the following Ajax functions, using jQuery:

$.ajax({
    url: $(this).data('url'),
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    traditional: true,
    data: JSON.stringify({ id: id, newPkgName: newPkgName}),
    success: function () {
        location.reload(true);
        successNotification("Package edited successfuly!");
    },
    error: function (message) {
        errorNotification(message);
    }
});

The problem with this code, is that even if the server returns the return "An error occurred, please try later! " + exc.Message; message in the catch, the success function is the one always called.

In order words, I never run the error function no matter what I do.

To fix this I checked the official documentation:

However, since I am failry new to this I can't understand any of the parameters, nor how to use them effectively.

How can I create a good error message with all the possible information using Ajax, jQuery and my controller?

2
  • can you try throw rather than return Commented Dec 2, 2014 at 10:05
  • error func calling if response status not OK(200), but if you catch exception on server, then you return response with status OK(200) so, simple not catch exception Commented Dec 2, 2014 at 10:06

2 Answers 2

6

The error part of the $.ajax call only fires if the returned status code is anything other than 200 OK. In your case you are returning a plaintext response which will therefore be 200. You can change this behaviour like this:

try {
    // do logic here
    return "OK";
}
catch (Exception exc) {
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Bad Request");
}
error: function (jqXHR, textStatus, errorThrown) {
    errorNotification(textStatus);
}

You can change the HttpStatusCode to whatever suits your need.

Alternatively, you can keep the 200 response and return JSON with a flag to indicate whether or not the request was successful:

[HttpPost]
public ActionResult EditPackage(int id, string newPkgName)
{
    try {
        //do logic here
        return Json(new { Success = true, Message = "OK"});
    }
    catch (Exception exc) {
        return Json(new { Success = false, Message = "An error occurred, please try later! " + exc.Message });
    }
}

Then you can remove the error handler, and check the state of the flag in your success handler:

success: function(response) {
    if (response.Success) {
        location.reload(true);
        successNotification("Package edited successfuly!");
    }
    else {
        errorNotification(response.Message); 
    }
},
Sign up to request clarification or add additional context in comments.

5 Comments

If I use the first approach, what changes do I need in my Ajax function ?
You don't need to make any changes to it.
To display the information correctly my error function needs to be error: function (jqXHR, textStatus, errorThrown ). If you add this to your response, I will gladly accept it :D
You're right - sorry I completely forgot that. I've updated my answer.
I used this return Json(new { Success = false, Message = "An error occurred, please try later! " + exc.Message }); but it's still returning 500, Internal Server Error, how can I use custom message?
1

I do the following, it might not be the best approach but it works for what I try to do.

[HttpPost]
public ActionResult EditPackage(int id, string newPkgName)
{
    try{
        //do logic here
        return Json(new {Success = true, Message = "OK"});
    }catch(Exception exc){
        return Json(new {Success = false, Message =  "An error occurred, please try later! " + exc.Message});
    }
}

Then my Ajax looks as follows:

$.ajax({
    url: $(this).data('url'),
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    traditional: true,
    data: JSON.stringify({ id: id, newPkgName: newPkgName}),
    success: function (data) {
        if(data.Success)
        {
            location.reload(true);
            successNotification("Package edited successfuly!");
        }
        else
        {
            errorNotification(data.Message);
        }
    },
    error: function (message) {
        errorNotification(message);
    }
});

I do this so that you have the standard error catching http errors from the server, but it means you can pass a success or failure back in a way that is more useful. It also means that if your update fails for a validation reason or something you can pass that message back nicely.

2 Comments

FYI Your syntax for creating the anonymous object is incorrect.
So it is, I'll correct it, sorry was being spoken to at the same time as typing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.