I am confused as to how to handle this situation.
我很困惑如何处理这种情况。
Usually when an unhandled ASP.Net exception occurs, the server sends back an HTML message of some sort, either the default Asp.Net error handler or a custom error handler. In either case though, HTML is being sent back (and usually it's a good idea to make the page user friendly).
通常,当发生未处理的ASP.Net异常时,服务器会发回某种HTML消息,默认的Asp.Net错误处理程序或自定义错误处理程序。在任何一种情况下,HTML都被发回(通常最好使页面用户友好)。
However, I am having an issue where the unhandled exceptions are occurring in Asp.net MVC controller actions that are expected to return JSON for Ajax calls. When the javascript reads the returned page (which is HTML instead of intended JSON) it crashes due to not being able to convert the response into JSON (right now I'm using ExtJS). I want Json to be returned upon an exception so that the user can be notified that an error has occurred.
但是,我遇到了一个问题,即在Asp.net MVC控制器操作中发生未处理的异常,这些操作有望为Ajax调用返回JSON。当javascript读取返回的页面(它是HTML而不是预期的JSON)时,由于无法将响应转换为JSON(现在我正在使用ExtJS)而崩溃。我希望在异常时返回Json,以便可以通知用户发生了错误。
The only solution I can think of is to do the following in every action that returns Json:
我能想到的唯一解决方案是在返回Json的每个操作中执行以下操作:
try { .... }
catch (Exception ex)
{
return Json(new { success = false, msg = ex.Message });
}
I don't like that method because it requires me catch all exceptions (which is bad for obvious reasons) and it requires me to pepper every JsonResult
action with that same exception handling code (which makes it hard to change later).
我不喜欢这种方法,因为它需要我捕获所有异常(由于显而易见的原因这是很糟糕的)并且它要求我用相同的异常处理代码(这使得以后很难更改)对每个JsonResult操作进行操作。
Is there a better method to return a more appropriate error result only on action methods that return Json, but still keep regular error pages user friendly for non-Ajax web requests?
是否有更好的方法只返回返回Json的操作方法更合适的错误结果,但仍然保持常规错误页面对非Ajax Web请求用户友好?
3 个解决方案
#1
12
Here's how I solved this problem:
这是我解决这个问题的方法:
public class HandleJsonError : HandleErrorAttribute
{
public override void OnException(ExceptionContext exceptionContext)
{
if (!exceptionContext.HttpContext.Request.IsAjaxRequest() || exceptionContext.Exception == null) return;
exceptionContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
exceptionContext.Result = new JsonResult
{
Data = new
{
exceptionContext.Exception.Message,
exceptionContext.Exception.StackTrace
}
};
exceptionContext.ExceptionHandled = true;
}
}
#2
3
You could override OnException in the controller and put in some logic to return a JSON error response which you would need to handle in your javascript calling code:
您可以在控制器中重写OnException并输入一些逻辑来返回您需要在javascript调用代码中处理的JSON错误响应:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = Json("...");
}
else
{
base.OnException(filterContext);
}
}
If you want to do it 'properly', you can write an actionfilter with pretty much the same code and apply it to all controllers. If you are using MVC3, you can make it a global filter so it will apply to all controllers.
如果你想'正确',你可以用几乎相同的代码编写一个actionfilter并将其应用到所有控制器。如果您使用的是MVC3,则可以将其设置为全局过滤器,以便它适用于所有控制器。
#3
1
You can use a custom ActionFilter and then inside of that if it was a javascript request you can then format the response as a JSON object instead of an HTML page. HandleError would be a good place to look at extending your base class from.
您可以使用自定义ActionFilter然后在其中如果是javascript请求,则可以将响应格式化为JSON对象而不是HTML页面。 HandleError是查看扩展基类的好地方。
An alternative option if you didn't want to do an actio filter would be to override OnException in your controller and set exceptionContext.Result to a new JsonResult that indicates failure.
如果您不想执行actio过滤器,另一种选择是覆盖控制器中的OnException,并将exceptionContext.Result设置为指示失败的新JsonResult。
#1
12
Here's how I solved this problem:
这是我解决这个问题的方法:
public class HandleJsonError : HandleErrorAttribute
{
public override void OnException(ExceptionContext exceptionContext)
{
if (!exceptionContext.HttpContext.Request.IsAjaxRequest() || exceptionContext.Exception == null) return;
exceptionContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
exceptionContext.Result = new JsonResult
{
Data = new
{
exceptionContext.Exception.Message,
exceptionContext.Exception.StackTrace
}
};
exceptionContext.ExceptionHandled = true;
}
}
#2
3
You could override OnException in the controller and put in some logic to return a JSON error response which you would need to handle in your javascript calling code:
您可以在控制器中重写OnException并输入一些逻辑来返回您需要在javascript调用代码中处理的JSON错误响应:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = Json("...");
}
else
{
base.OnException(filterContext);
}
}
If you want to do it 'properly', you can write an actionfilter with pretty much the same code and apply it to all controllers. If you are using MVC3, you can make it a global filter so it will apply to all controllers.
如果你想'正确',你可以用几乎相同的代码编写一个actionfilter并将其应用到所有控制器。如果您使用的是MVC3,则可以将其设置为全局过滤器,以便它适用于所有控制器。
#3
1
You can use a custom ActionFilter and then inside of that if it was a javascript request you can then format the response as a JSON object instead of an HTML page. HandleError would be a good place to look at extending your base class from.
您可以使用自定义ActionFilter然后在其中如果是javascript请求,则可以将响应格式化为JSON对象而不是HTML页面。 HandleError是查看扩展基类的好地方。
An alternative option if you didn't want to do an actio filter would be to override OnException in your controller and set exceptionContext.Result to a new JsonResult that indicates failure.
如果您不想执行actio过滤器,另一种选择是覆盖控制器中的OnException,并将exceptionContext.Result设置为指示失败的新JsonResult。