How to return error from ASP.NET MVC action
I am using ASP.NET MVC for developing a web site. I am using jquery for AJAX functionality. In the action methods, I want to return some error to signal that the input is not correct or that the action could not be performed. In such error cases, I expect the jquery ajax error handler to be called and I can take appropriate action in there. I have not found a way how to do this. Following is my action method.
In error cases, what should I be sending from an Action in order to get the jquery error handler triggered?
开发者_开发技巧public ActionResult AddToFavourites(int entityId, string entityType)
{
if (!Request.IsAjaxRequest())
throw new InvalidOperationException("This action can be called only in async style.");
try
{
RBParams.EntityType typeOfFavourite = (RBParams.EntityType)Enum.Parse(typeof(RBParams.EntityType), entityType);
string status = "";
if (typeOfFavourite == RBParams.EntityType.BusinessEntity)
{
status = MarkFavouriteEntity(entityId);
}
else if (typeOfFavourite == RBParams.EntityType.Review)
{
status = MarkFavouriteReview(entityId);
}
else
{
throw new InvalidOperationException("The type of the entity is not proper");
}
return Content(status);
}
catch (Exception ex)
{
return Content("Error");
}
}
Your ajax error handler will be called when the action doesn't return a expected status code. It will, for example, fire if the action wasn't found or if you throw a exception that you don't handle. In your case it will be called if you don't catch the error in your action (as the action will return a 500 status code).
I would, however, not do it in this way as this is probably a expected error. I would rather return json both when you succeed and when you have a error. Then you can indicate if it is a successful call or not. Something like this:
public ActionResult AddToFavourites(int entityId, string entityType)
{
if (!Request.IsAjaxRequest())
throw new InvalidOperationException("This action can be called only in async style.");
try
{
RBParams.EntityType typeOfFavourite = (RBParams.EntityType)Enum.Parse(typeof(RBParams.EntityType), entityType);
string status = "";
if (typeOfFavourite == RBParams.EntityType.BusinessEntity)
{
status = MarkFavouriteEntity(entityId);
}
else if (typeOfFavourite == RBParams.EntityType.Review)
{
status = MarkFavouriteReview(entityId);
}
else
{
throw new InvalidOperationException("The type of the entity is not proper");
}
return Json(new { Success = true, Status = status });
}
catch (Exception ex)
{
return Json(new { Success = false, Message = ex.Message });
}
}
Then you handle it in the same way as a successful call. You just check the Success property of your json response. Then you handle unexpected errors in the error callback.
Mattias Jakobsson's answer is right. But I think the best way to return the error to the jQuery is creating a JSON and sending it with status 500. However, when I did it and tried to deploy my MVC website using IIS 7 I figured out that it was returning me the custom page instead of the message.
The code was...
catch (Exception ex)
{
Response.StatusCode = 500;
return Json(new { error = ex.Message });
}
But then I saw this thread that led me to this web site (from Rick Strahl).
Overall, I understood that you need to say to IIS to not inject the custom error page, so you need this flag (in the global.asax or into the catch):
Response.TrySkipIisCustomErrors = true;
So, in jQuery the code keeps the same:
$.ajax({...})
.done(function (result) {...})
.fail(function (e) {
console.log(e.responseJSON.error);
});
you shoud config jquery to handle error:
$.ajaxSetup({
error: function(xhr) {
alert(xhr.statusText);
}
})
精彩评论