![](/img/trans.png)
[英]AuthorizationHandler exception not going through 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.