DotNet Core 3.1 全局错误处理,未调用中间件
DotNetCore 3.1 global error handling, middle ware not getting called
我正在尝试在 .NetCore 3.1 webpai 中设置全局异常处理代码
我的目标是在应用程序退出之前使用 log4net 记录未处理的异常。
我尝试遵循几个教程,一个使用过滤器,几个使用中间件,当我完成并测试它时,当我因此抛出异常时,中间件永远不会被调用。
我已经有一个过滤器(它被注释掉以测试中间件以防它们交互)它确实有效,但不能使用 IOC 加载 ILogger 的实例
[HttpGet]
[Route( "/ThrowException" )]
public JqGridReturnCV ThrowException()
{
log.LogTrace( "AdStudentController::ThrowException() - in" );
throw new Exception( "This is a test Exception" );
log.LogTrace( "AdStudentController::ThrowException() - out" );
}
这是我的中间件代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using log4net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using StudentPortal4Api.Dto;
namespace StudentPortal4Api.Utilities
{
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate next;
public readonly ILogger log;
public GlobalExceptionMiddleware( RequestDelegate _next, ILogger _log )
{
next = _next;
log = _log;
}
public async Task Invoke( HttpContext context )
{
try
{
await next( context );
}
catch ( Exception ex )
{
var response = context.Response;
response.ContentType = "application/json";
switch ( ex )
{
default:
// unhandled error
log.Log( LogLevel.Error, " GlobalException:" + ex.ToString() );
break;
}
throw;
}
}
}
public class ErrorDetails
{
public int StatusCode { get; set; }
public string Message { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject( this );
}
}
public static class ExceptionMiddlewareExtensions
{
public static void ConfigureExceptionHandler( this IApplicationBuilder app, ILogger logger )
{
app.UseExceptionHandler( appError =>
{
appError.Run( async context =>
{
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if ( contextFeature != null )
{
logger.LogError( $"Something went wrong: {contextFeature.Error}" );
await context.Response.WriteAsync( new ErrorDetails()
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error."
}.ToString() );
}
} );
} );
}
}
}
这是我的配置方法,我怀疑我在注册它时做错了什么
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure( IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, ILogger log )
{
//code removed for clarity
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//Code removed for clarity
// global error handler
app.UseMiddleware<GlobalExceptionMiddleware>();
app.ConfigureExceptionHandler( log );
}
}
}
有人看到我做错了什么了吗?
您有订单问题source
更改为:
app.UseAuthorization();
// global error handler
app.UseMiddleware<GlobalExceptionMiddleware>(); //custom Middleware Must be before endpoints and after auth.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
您将不需要 app.UseExceptionHandler。
我正在尝试在 .NetCore 3.1 webpai 中设置全局异常处理代码
我的目标是在应用程序退出之前使用 log4net 记录未处理的异常。
我尝试遵循几个教程,一个使用过滤器,几个使用中间件,当我完成并测试它时,当我因此抛出异常时,中间件永远不会被调用。
我已经有一个过滤器(它被注释掉以测试中间件以防它们交互)它确实有效,但不能使用 IOC 加载 ILogger 的实例
[HttpGet]
[Route( "/ThrowException" )]
public JqGridReturnCV ThrowException()
{
log.LogTrace( "AdStudentController::ThrowException() - in" );
throw new Exception( "This is a test Exception" );
log.LogTrace( "AdStudentController::ThrowException() - out" );
}
这是我的中间件代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using log4net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using StudentPortal4Api.Dto;
namespace StudentPortal4Api.Utilities
{
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate next;
public readonly ILogger log;
public GlobalExceptionMiddleware( RequestDelegate _next, ILogger _log )
{
next = _next;
log = _log;
}
public async Task Invoke( HttpContext context )
{
try
{
await next( context );
}
catch ( Exception ex )
{
var response = context.Response;
response.ContentType = "application/json";
switch ( ex )
{
default:
// unhandled error
log.Log( LogLevel.Error, " GlobalException:" + ex.ToString() );
break;
}
throw;
}
}
}
public class ErrorDetails
{
public int StatusCode { get; set; }
public string Message { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject( this );
}
}
public static class ExceptionMiddlewareExtensions
{
public static void ConfigureExceptionHandler( this IApplicationBuilder app, ILogger logger )
{
app.UseExceptionHandler( appError =>
{
appError.Run( async context =>
{
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if ( contextFeature != null )
{
logger.LogError( $"Something went wrong: {contextFeature.Error}" );
await context.Response.WriteAsync( new ErrorDetails()
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error."
}.ToString() );
}
} );
} );
}
}
}
这是我的配置方法,我怀疑我在注册它时做错了什么
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure( IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, ILogger log )
{
//code removed for clarity
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//Code removed for clarity
// global error handler
app.UseMiddleware<GlobalExceptionMiddleware>();
app.ConfigureExceptionHandler( log );
}
}
}
有人看到我做错了什么了吗?
您有订单问题source
更改为:
app.UseAuthorization();
// global error handler
app.UseMiddleware<GlobalExceptionMiddleware>(); //custom Middleware Must be before endpoints and after auth.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
您将不需要 app.UseExceptionHandler。