簡體   English   中英

引用標准庫后,異常不會轉到ExceptionFilter

[英]Exception not going to ExceptionFilter after referencing Standard lib

我在.NET 4.6.1上有一個傳統的WebApi項目,該項目具有全局ExceptionFilter ,該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());
}

MyExceptionFilterAttribute.cs

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);
    }
}

MyController.cs

public class MyController : ApiController
{
    public async Task<IHttpActionResult> Get()
    {
        await Task.Run(() => { throw new ArgumentNullException("Error"); });
        return Ok();
    }
}

按原樣致電時,我會收到400

但是,當添加對.NETStandard 2.0 lib的引用時,該異常不會轉到ExceptionFilter並且出現以下錯誤:

{
    "message": "An error has occurred.",
    "exceptionMessage": "Method not found: 'System.Net.Http.HttpRequestMessage System.Web.Http.Filters.HttpActionExecutedContext.get_Request()'.",
    "exceptionType": "System.MissingMethodException",
    "stackTrace": "   at MyApi.Filters.MyExceptionFilterAttribute.OnException(HttpActionExecutedContext context)\r\n   at System.Web.Http.Filters.ExceptionFilterAttribute.OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ExceptionFilterAttribute.<ExecuteExceptionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

任何幫助表示贊賞。

使用.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中。 嘗試調用它時,它顯示出與上述相同的異常。

在這里對我MyLoggerAdapter一種解決方法是在Web項目引用的另一個庫(非.NETStandart 2.0)(在我的情況下是業務層庫)中定義一個.Net框架適配器MyLoggerAdapter

public interface ILoggerCompatable
{
    void Error(string message, object data, params string[] tags);
}

public class MyLoggerAdapter : ILoggerCompatable
{
    private readonly MyLogger _logger;

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

    public void Error(string message, object data, params string[] tags) => _logger.Error(message, data, tags.Select(tag => (Tag)tag).ToArray());
}

因此,從該源.NETStandart庫中看不到任何內容,然后將其注入到處理程序中(通過Autofac):

public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
    private readonly ILoggerCompatable _logger;

    private const string ExceptionOccuredLoggingTag = "ExceptionOccured";

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


    public override void OnException(HttpActionExecutedContext context)
    {
        ...
        _logger.Error(errorMessage,
            context.Exception,
            mostRecentFrame.Class.Name,
            mostRecentFrame.Method.Name,
            ExceptionOccuredLoggingTag);
        ...);
    }
}

過濾器注冊如下所示:

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運行時: https : //www.microsoft.com/net/download

PS:此問題發生在未安裝.net framewokr 4.7.x的Windows 7和Windows Server 2008 R2上,默認情況下在未安裝.net framewokr 4.7.x的Windows 10上也不會出現。

抱歉,我還沒有發布答案。 因此,我們發現將標准項目添加到.NET Framework項目時某些API不兼容。 另一個示例是在控制器中訪問User 將Standard項目添加到.NET Framework ASP.NET項目后,在運行時將無法訪問此項目(甚至可能引發異常)。

為了100%的兼容性,我們最終以Standard編寫了新庫,同時以.NET 4.6、4.6.1和4.6.2為目標,因為我們的項目仍在這些庫下運行。 我們將這些包上傳到我們的nuget提要中,它允許我們的其他應用程序引用正確的二進制文件。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM