C# 引用标准库后,Exception不会转到ExceptionFilter

C# 引用标准库后,Exception不会转到ExceptionFilter,c#,C#,我在.NET 4.6.1上有一个传统的WebApi项目,其中有一个全局ExceptionFilter,它处理已知的异常,以返回带有相应状态代码的友好消息 WebApiConfig.cs public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi",

我在.NET 4.6.1上有一个传统的WebApi项目,其中有一个全局
ExceptionFilter
,它处理已知的异常,以返回带有相应状态代码的友好消息

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    config.Filters.Add(new MyExceptionFilterAttribute());
}
internal sealed class GatewayExceptionFilterAttribute : ExceptionFilterAttribute
{
    private static readonly Dictionary<Type, HttpStatusCode> Exceptions = new Dictionary<Type, HttpStatusCode>
    {
        // HTTP 400
        [typeof(ArgumentException)] = HttpStatusCode.BadRequest,
        [typeof(ArgumentNullException)] = HttpStatusCode.BadRequest,
    };

    public override void OnException(HttpActionExecutedContext context)
    {
        var type = context.Exception.GetType();

        if (context.Exception is HttpResponseException)
            return;

        // Return 500 for unspecified errors
        var status = HttpStatusCode.InternalServerError;
        var message = Strings.ERROR_INTERNAL_ERROR;

        if (Exceptions.ContainsKey(type))
        {
            status = Exceptions[type];
            message = context.Exception.Message;
        }

        context.Response = context.Request.CreateErrorResponse(status, message);
    }
}
public class MyController : ApiController
{
    public async Task<IHttpActionResult> Get()
    {
        await Task.Run(() => { throw new ArgumentNullException("Error"); });
        return Ok();
    }
}
MyExceptionFilterAttribute.cs

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    config.Filters.Add(new MyExceptionFilterAttribute());
}
internal sealed class GatewayExceptionFilterAttribute : ExceptionFilterAttribute
{
    private static readonly Dictionary<Type, HttpStatusCode> Exceptions = new Dictionary<Type, HttpStatusCode>
    {
        // HTTP 400
        [typeof(ArgumentException)] = HttpStatusCode.BadRequest,
        [typeof(ArgumentNullException)] = HttpStatusCode.BadRequest,
    };

    public override void OnException(HttpActionExecutedContext context)
    {
        var type = context.Exception.GetType();

        if (context.Exception is HttpResponseException)
            return;

        // Return 500 for unspecified errors
        var status = HttpStatusCode.InternalServerError;
        var message = Strings.ERROR_INTERNAL_ERROR;

        if (Exceptions.ContainsKey(type))
        {
            status = Exceptions[type];
            message = context.Exception.Message;
        }

        context.Response = context.Request.CreateErrorResponse(status, message);
    }
}
public class MyController : ApiController
{
    public async Task<IHttpActionResult> Get()
    {
        await Task.Run(() => { throw new ArgumentNullException("Error"); });
        return Ok();
    }
}

非常感谢您的帮助。

我在使用.Net 4.6.2 Web API时遇到了同样的问题。 我在Web项目中定义了以下异常处理程序:

public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
    private readonly MyLogger _logger;

    private const string ExceptionOccuredLoggingTag = "ExceptionOccured";

    public ExceptionHandlerAttribute(MyLogger logger)
    {
        _logger = logger;
    }


    public override void OnException(HttpActionExecutedContext context)
    {
        ...
        _logger.Error(errorMessage,
            context.Exception,
            mostRecentFrame.Class.Name,
            mostRecentFrame.Method.Name,
            ExceptionOccuredLoggingTag);
        ...
    }
}
其中,
MyLogger
类是在中定义的,它位于另一个.NETStandart 2.0 dll中。当我试图调用它时,它显示了与上面相同的异常

在这里对我有效的一个解决方法是在web项目引用的另一个库(非.NETStandart 2.0)中定义.Net framework适配器
MyLoggerAdapter
(在我的例子中是业务层库):

因此,从源.NETStandart库中看不到任何内容,然后将其注入处理程序(通过Autofac):

过滤器注册如下所示:

var loggerCompatable = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(ILoggerCompatable)) as ILoggerCompatable;
GlobalConfiguration.Configuration.Filters.Add(new ExceptionHandlerAttribute(loggerCompatable));
希望这有帮助

我也有这个问题

安装.net framewokr 4.7.2运行时后,问题已解决

您可以在此处获取.net framewokr 4.7.2运行时:

PS:此问题发生在未安装.net framewokr 4.7.x的windows 7和windows server 2008 R2上,
默认情况下带有.net framewokr 4.7.x的windows 10上不显示。很抱歉,我没有发布答案。因此,我们发现在向.NET Framework项目添加标准项目时,某些API不兼容。另一个例子是访问控制器中的
用户
。一旦将标准项目添加到.NET Framework ASP.NET项目中,您将无法在运行时访问该项目(甚至可能引发异常)

为了100%的兼容性,我们最终以标准编写了我们的新库,同时以.NET 4.6、4.6.1和4.6.2为目标,因为我们的项目仍然在这些标准下运行。我们将这些包上传到我们的nuget提要,它允许我们的其他应用程序引用正确的二进制文件


希望这有帮助

非常相似的问题在这里描述了一个结论,我认为这是两个不同的问题。他的问题是他想让
ExceptionFilter
完成所有的异常处理,甚至是来自其他过滤器的异常处理,这不是
ExceptionFilter
的设计方式。此外,他最终实现了一个以ASP为核心的解决方案。我还在使用WebApi。我还不能皈依。