【问题标题】:How to handle an exception only once in asp.net mvc如何在asp.net mvc中只处理一次异常
【发布时间】:2020-09-10 21:41:01
【问题描述】:

我想在我的 ASP.Net MVC 5 应用程序中记录异常。在 stackoverflow 和其他地方进行了研究之后,我发现了几种在 .Net 应用程序中记录异常的方法。我在Web.config 中启用了自定义错误模式,并带有 500 和 404 错误状态代码重定向。正如不同意见所建议的那样,Global.asax 中的Application_Error 总是很好地必须捕获一些开箱即用的异常,并在基本控制器中使用 OnException 覆盖方法来捕获任何继承的控制器或操作方法异常。

但是我发现的问题,Application_Error 没有提供有关异常的很多具体细节,即使在 BaseController OnException 方法中捕获了相同的异常,它也在 Application_Error 中冒泡。我在OnException 中这样做的方式有点像以下-

    protected override void OnException(ExceptionContext filterContext)
    {
        var ex = filterContext.Exception;
        filterContext.ExceptionHandled = true;
        Server.ClearError();
        base.OnException(filterContext);
    }

真的有可能限制在OnException 方法中处理的不冒泡到Application_Error 的异常吗?我还想知道是否有可能在Application_Error 中获得特定于异常的详细信息。

【问题讨论】:

    标签: c# asp.net-mvc exception


    【解决方案1】:

    ASP.NET MVC 中的异常处理

    创建一个自定义的“HandleErrorAttribute”类:

    public class CustomErrorHandler : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            //If the request is AJAX return JSON, else return View
            if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
            {
                // Log exception first
                filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
    
                filterContext.Result = new JsonResult
                {
                    Data = new
                    {
                        success = false,
                        message = "An error occured while sending form.",
                        type = filterContext.Exception.GetType().Name,
                        exception = filterContext.Exception.ToString()
    
                        //Message = "Error Processing your request. Technical detail: " + filterContext.Exception.Message,
                        //TechnicalDetails = filterContext.Exception.Message + System.Environment.NewLine + filterContext.Exception.StackTrace
                    },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
    
                // Let the system know that the exception has been handled
                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.Clear();
    
                // Avoid IIS7 getting in the middle
                //Response.TrySkipIisCustomErrors = true;
            }
            else
            {
                // Normal Exception. So, let it handle by its default ways
                base.OnException(filterContext);
            }
            // Write error logging code here if you wish.
    
            // If want to get different of the request
            //var currentController = (string)filterContext.RouteData.Values["controller"];
            //var currentActionName = (string)filterContext.RouteData.Values["action"];
        }
    }
    

    将这个类装饰为跨控制器或动作方法的属性(无需使用 try-catch 块)

    [CustomErrorHandler]
    public JsonResult DeleteConfirmed(int id)
    {
        if (ModelState.IsValid)
        {
            Schedule schedule = repository.Schedules.FirstOrDefault(m => m.Id == id);
            if (schedule == null)
            {
                return Json(new { success = false, message = "User not found." });
            }
            else
            {
                Schedule deletedSchedule = repository.DeleteSchedulePermanently(id);
                if (deletedSchedule != null)
                {
                    return Json(new { success = true, message = "Succeeded" });
                }
            }
        }
        // If we got this far, something failed, redisplay form
        return Json(new { success = false, message = "Please check errors." });
    }
    

    在AJAX调用中,获取自定义“HandleErrorAttribute”类中创建的异常属性。

    $.ajax({
    
        //code omitted for brevity 
    
        error: function (jqXHR, textStatus, errorThrown) {
            if (jqXHR.status == 401) {
                // perform a redirect to the login page since we're no longer authorized
            }
            if (jqXHR.responseJSON != null) {
                displayAlert('danger', 'warning', jqXHR.responseJSON.message + " Error Details: " + jqXHR.responseJSON.exception, '#result');
            }
        },
        success: function (response, textStatus, XMLHttpRequest) {
            if (response.success) {
                showToast('success', 'Result', response.message, 'toast-top-right');
            }
            else {
                displayAlert('danger', 'warning', response.message, '#result');
            }
        }
    });
    

    【讨论】:

    • 感谢和抱歉我迟到的回复。我的主要目的是记录而不是重定向。您的最后一个示例已经到位。我已经尝试过CustomErrorHandler,但是在整个控制器和方法中使用它感觉就像手动操作一样。所以我在现有的BaseController 上更喜欢OnException。如果使用CustomErrorHandler 而不是OnException 有更多好处,您可以遮住一些光线。不过,我已经找到了解决异常情况的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 2017-08-20
    • 2012-09-17
    • 2010-10-23
    • 2012-05-04
    • 1970-01-01
    相关资源
    最近更新 更多