C# 在Asp.NETMVC针对Ajax请求的操作中,处理未处理异常(错误500响应)的最佳策略是什么?
我对如何处理这种情况感到困惑 通常,当发生未处理的ASP.Net异常时,服务器会发回某种类型的HTML消息,可以是默认的ASP.Net错误处理程序,也可以是自定义的错误处理程序。不过,不管是哪种情况,HTML都会被发回(通常,让页面变得友好是个好主意) 但是,我遇到了一个问题,即Asp.net MVC控制器操作中出现了未处理的异常,这些操作预期会为Ajax调用返回JSON。当javascript读取返回的页面(是HTML而不是预期的JSON)时,由于无法将响应转换为JSON(现在我使用的是ExtJS),它会崩溃。我希望在出现异常时返回Json,以便通知用户发生错误 我能想到的唯一解决方案是在每个返回Json的操作中执行以下操作:C# 在Asp.NETMVC针对Ajax请求的操作中,处理未处理异常(错误500响应)的最佳策略是什么?,c#,asp.net-mvc,json,exception-handling,C#,Asp.net Mvc,Json,Exception Handling,我对如何处理这种情况感到困惑 通常,当发生未处理的ASP.Net异常时,服务器会发回某种类型的HTML消息,可以是默认的ASP.Net错误处理程序,也可以是自定义的错误处理程序。不过,不管是哪种情况,HTML都会被发回(通常,让页面变得友好是个好主意) 但是,我遇到了一个问题,即Asp.net MVC控制器操作中出现了未处理的异常,这些操作预期会为Ajax调用返回JSON。当javascript读取返回的页面(是HTML而不是预期的JSON)时,由于无法将响应转换为JSON(现在我使用的是Ext
try { .... }
catch (Exception ex)
{
return Json(new { success = false, msg = ex.Message });
}
我不喜欢这种方法,因为它要求我捕获所有异常(这显然是不好的),并且要求我在每个JsonResult
操作中添加相同的异常处理代码(这使得以后很难更改)
是否有更好的方法仅在返回Json的操作方法上返回更合适的错误结果,但是对于非Ajax web请求,仍然保持常规错误页面用户友好?您可以使用自定义ActionFilter,然后在其中,如果是javascript请求,则可以将响应格式化为JSON对象,而不是HTML页面。HandleError将是一个考虑扩展基类的好地方
如果您不想执行actio筛选器,另一种选择是覆盖控制器中的OneException,并将exceptionContext.Result设置为新的JsonResult,表示失败。以下是我解决此问题的方法:
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;
}
}
您可以在控制器中重写OneException,并加入一些逻辑以返回JSON错误响应,您需要在javascript调用代码中处理该响应:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = Json("...");
}
else
{
base.OnException(filterContext);
}
}
如果您想“正确地”执行此操作,可以使用几乎相同的代码编写actionfilter,并将其应用于所有控制器。如果您使用的是MVC3,则可以将其设置为全局筛选器,以便将其应用于所有控制器。您可能希望从HandleErrorAttribute继承,并重写OneException。这样,你的过滤器只有在出现异常时才会启动,而不是针对每个请求启动。由于代码原因,将此标记为答案@卖花人:哦,嗯,听起来不错。有机会的话我会试一试。谢谢客户端已经设置为确定是否发生了500错误,并解析它接收到的任何json。问题是,在此解决方案之前,服务器只返回HTML错误响应,我需要一个JSON错误响应。@adamjford幸运的是,我已经在使用Elmah,所以我知道它是什么。我很高兴您添加了这个,因为手动记录错误非常重要,因为如果您设置ExceptionHandling=true,将阻止Elmah进入。并且ExceptionHandling=true似乎是必需的,否则您将获得默认的HTML 500响应。在代码“正常”的情况下,try/catch也没有帮助,但异常仅在框架尝试执行ActionResult时发生-例如,如果您返回一个具有uint64值的对象,则会出现json序列化错误,即使代码中没有抛出异常。因此,您需要接受答案中的筛选器或OneException处理程序。