Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 全局异常筛选器或应用程序错误均未捕获未处理的异常_C#_Asp.net Mvc_Asp.net Mvc 4_Exception Handling_Automapper - Fatal编程技术网

C# 全局异常筛选器或应用程序错误均未捕获未处理的异常

C# 全局异常筛选器或应用程序错误均未捕获未处理的异常,c#,asp.net-mvc,asp.net-mvc-4,exception-handling,automapper,C#,Asp.net Mvc,Asp.net Mvc 4,Exception Handling,Automapper,我有一个名为LogErrorAttribute的全局异常筛选器: public class LogErrorAttribute : IExceptionFilter { private ILogUtils logUtils; public void OnException(ExceptionContext filterContext) { if (this.logUtils == null) { this.logU

我有一个名为
LogErrorAttribute
的全局异常筛选器:

public class LogErrorAttribute : IExceptionFilter
{
    private ILogUtils logUtils;

    public void OnException(ExceptionContext filterContext)
    {
        if (this.logUtils == null)
        {
            this.logUtils = StructureMapConfig.Container.GetInstance<ILogUtils>();
        }

        this.logUtils.LogError(HttpContext.Current.User.Identity.GetUserId(), "Unknown error.", filterContext.Exception);
    }
}
我正在注册这些过滤器,如下所示:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
我还有一个
应用程序\u错误
回退:

protected void Application_Error()
{
    var exception = Server.GetLastError();
    Server.ClearError();
    var httpException = exception as HttpException;

    //Logging goes here

    var routeData = new RouteData();
    routeData.Values["controller"] = "Error";
    routeData.Values["action"] = "Index";

    if (httpException != null)
    {
        if (httpException.GetHttpCode() == 404)
        {
            routeData.Values["action"] = "NotFound";
        }
        Response.StatusCode = httpException.GetHttpCode();
    }
    else
    {
        Response.StatusCode = 500;
    }

    // Avoid IIS7 getting involved
    Response.TrySkipIisCustomErrors = true;

    // Execute the error controller
    if (exception != null)
    {
        this.errorLogger.Log(LogLevel.Error, "An unknown exception has occurred.", exception);
    }
    else if (httpException != null)
    {
        this.errorLogger.Log(LogLevel.Error, "An unknown HTTP exception has occurred.", httpException);
    }
    else
    {
        this.errorLogger.Log(LogLevel.Error, "An unknown error has occurred.");
    }
}
现在,我有一个API控制器,它从数据库中获取一些数据,然后使用
AutoMapper
将模型映射到视图模型:

var viewModels = AutoMapper.Mapper.Map(users, new List<UserViewModel>());
目前,我正在强制appModuleManager.Get语句抛出一个常规异常:

throw new Exception("Testing global filter.");
这随后会在
自动映射
中引发一个异常,这两个异常都未处理,但是全局筛选器或
应用程序错误
均未检测到此异常

我做错了什么


发帖后我做了几件事:

  • customErrors
    属性添加到
    Web.config
    以将其打开
  • 删除了
    HandleErrorAttribute
    全局筛选器,因为我意识到它正在将错误设置为handle(如果它正在运行)。我不希望它会执行,因为这个错误发生在控制器之外,但它可能会在以后咬我

  • 简单的回答是,您正在添加一个MVC异常过滤器,而不是WebAPI异常过滤器

    您的实现将检查
    ExceptionContext
    而不是
    HttpActionExecutedContext

    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    
    由于框架将引发Http异常而不是MVC异常,因此不会触发
    OneException
    覆盖方法

    下面是一个更完整的例子:

    public class CustomExceptionFilter : ExceptionFilterAttribute
    
        {
           public override void OnException(HttpActionExecutedContext actionExecutedContext)
    
          {
    
            message = "Web API Error";
            status = HttpStatusCode.InternalServerError;
    
            actionExecutedContext.Response = new HttpResponseMessage()
            {
                Content = new StringContent(message, System.Text.Encoding.UTF8, "text/plain"),
                StatusCode = status
            };
    
            base.OnException(actionExecutedContext);
        }
    }
    
    另一个重要步骤是在WebApiConfig.cs中的
    register(HttpConfiguration config)
    方法中注册全局Web API异常过滤器

    public static void Register(HttpConfiguration config)
    {
    
    ...
    
    config.Filters.Add(new CustomExceptionFilter());
    
    }
    

    Dave Alperovich answer将使用HttpActionExecutedContext解决您的问题

    public override void OnException(HttpActionExecutedContext context)
    
    然而,当您试图捕获应用程序可能生成的所有可能的异常时,除了异常过滤器之外,还应该使用消息处理程序。详细的解释可以在这里找到-

    总之,有许多异常筛选器无法处理的情况。例如:

    • 从控制器构造函数引发的异常
    • 从消息处理程序引发的异常
    • 路由过程中引发的异常
    • 响应内容序列化期间引发的异常
    因此,如果在应用程序中的任何位置发生未经处理的错误,异常处理程序将捕获该错误并允许您采取特定操作

    //Global exception handler that will be used to catch any error
    public class MyExceptionHandler : ExceptionHandler
        {
            private class ErrorInformation
            {
                public string Message { get; set; }
                public DateTime ErrorDate { get; set; }            
            }
    
            public override void Handle(ExceptionHandlerContext context)
            {
                context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError, 
                  new ErrorInformation { Message="An unexpected error occured. Please try again later.", ErrorDate=DateTime.UtcNow }));
            }
       }
    

    我讨厌成为“那个家伙”,但你有没有尝试过清理(删除)bin和obj文件夹,然后清除web浏览器缓存?看起来你做的每件事都是正确的(从最初的一瞥来看)@笔名我完全理解,但是的,我一直在走这条路。好的,我将不得不仔细阅读你的问题。唯一的应用程序错误在我们所有的mvc应用程序中都有效,不需要过滤器。我不记得这里有什么额外的东西了。@WiktorZychla正是我猜想它应该如何工作的。哈哈。这是不是碰巧和你认为的
    AutoMapper
    有关?我不这么认为,因为即使是
    AutoMapper
    异常也没有得到处理。我将尝试一下这个更改。但是,即使这修复了过滤器,为什么全局处理程序没有发现错误?@MichaelPerrenoud,我补充了我的答案。jist是HTTP上下文不同于MVC上下文。对原因的解释相当复杂。最简单的解释是,WebAPI是一个比完整的MVC轻得多的框架Framework@DaveAlperovich-我不知道你是怎么得出这个结论的。OP没有给出任何迹象表明他正在使用Web API,无论是问题本身还是标签。所以,由于他显然要尝试,你的假设似乎是正确的。还有一种情况是,有人错误地标记了他们的问题,因为这似乎与ASP.NETMVC毫无关系,ASP.NETMVC是一个与WebAPI完全不同的框架。我相信如果问题中包含了这些信息,答案会来得更快。@DaveAlperovich您是对的,它是一个Web API控制器。我今天要尝试这个解决方案。我会再打给你。没错,你必须使用ExceptionFilterAttribute或IFilter来实现web api的过滤器。您不能像在mvc管道中那样捕获全局错误。
    public override void OnException(HttpActionExecutedContext context)
    
    //Global exception handler that will be used to catch any error
    public class MyExceptionHandler : ExceptionHandler
        {
            private class ErrorInformation
            {
                public string Message { get; set; }
                public DateTime ErrorDate { get; set; }            
            }
    
            public override void Handle(ExceptionHandlerContext context)
            {
                context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError, 
                  new ErrorInformation { Message="An unexpected error occured. Please try again later.", ErrorDate=DateTime.UtcNow }));
            }
       }