asp.net 核心 2 异常未显示问题所在
asp.net core 2 exception not showing where the issue is
我有一个 asp.net coree 2 网络应用程序。我使用中间件过滤器,因为它是一个多租户应用程序。
app.UseMiddleware<TenantMiddleware>();
并且在中间件
public class TenantMiddleware
{
private readonly RequestDelegate _next;
public TenantMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
...
await _next.Invoke(httpContext);
}
}
问题是,当我遇到异常时,堆栈跟踪总是指向中间件,而不是向我显示问题出在哪里。如果我删除中间件,异常跟踪会告诉我发生异常的确切行,但对于中间件,它始终是相同的跟踪:
第一行是更改并显示真正问题的行,这很好:
NullReferenceException: Object reference not set to an instance of an object.
但堆栈跟踪毫无意义
Microsoft.AspNetCore.Mvc.Internal.MiddlewareFilterBuilder+<>c+<<BuildPipeline>b__8_0>d.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
MyWebApp.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
await _next.Invoke(httpContext);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()
始终显示 Tenent 中间件而不是发生错误的页面行
MyWebApp.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
await _next.Invoke(httpContext);
有没有办法让堆栈跟踪指向发生错误的页面?
谢谢。
更新
感谢陶老师的回答,我想出了一个可能的原因。
问题出在 Startup.cs,在 COnfigureServices:
services.AddMvc(options =>
{
options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipeline)));
});
和 LocalizationPipeline:
public class LocalizationPipeline
{
public void Configure(IApplicationBuilder appBuilder, RequestLocalizationOptions options)
{
appBuilder.UseRequestLocalization(options);
}
}
当我删除那条线时,轨迹看起来像:
DivideByZeroException: Attempted to divide by zero.
MyWebApp.Web.Controllers.TestController.Index() in TestController.cs
+
var c = b / a;
lambda_method(Closure , object , Object[] )
Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(object target, Object[] parameters)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__12.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextActionFilterAsync>d__10.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeInnerFilterAsync>d__14.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
MyWebApp.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
await _next.Invoke(httpContext);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()
知道为什么要从跟踪中删除所有信息吗?任何可能的解决方案?
这个问题是由MiddlewareFilterBuilder
引起的。
对于 Asp.Net Core 2.0
项目,Microsoft.AspNetCore.Mvc.Core
是 Version 2.0.4
有这个错误。 Version 2.1.0
通过添加 resourceExecutedContext.ExceptionDispatchInfo?.Throw();.
解决了这个问题
解决方案:
尝试使用来自 Nuget window 的 Version 2.1.2
安装 Microsoft.AspNetCore.Mvc.Core
。
解决方法
MiddlewareFilterBuilder
的自定义实现。
- 添加MiddlewareFilter
- 添加MiddlewareFilterAttribute
- 添加MiddlewareFilterBuilder
- 添加MiddlewareFilterBuilderStartupFilter
修改Startup.cs
ConfigureService
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipeline)));
});
services.AddSingleton<RequestLocalizationOptions>();
services.AddSingleton<MiddlewareFilterBuilder>();
services.Add(ServiceDescriptor.Singleton<IStartupFilter, MiddlewareFilterBuilderStartupFilter>());
}
我有一个 asp.net coree 2 网络应用程序。我使用中间件过滤器,因为它是一个多租户应用程序。
app.UseMiddleware<TenantMiddleware>();
并且在中间件
public class TenantMiddleware
{
private readonly RequestDelegate _next;
public TenantMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
...
await _next.Invoke(httpContext);
}
}
问题是,当我遇到异常时,堆栈跟踪总是指向中间件,而不是向我显示问题出在哪里。如果我删除中间件,异常跟踪会告诉我发生异常的确切行,但对于中间件,它始终是相同的跟踪:
第一行是更改并显示真正问题的行,这很好:
NullReferenceException: Object reference not set to an instance of an object.
但堆栈跟踪毫无意义
Microsoft.AspNetCore.Mvc.Internal.MiddlewareFilterBuilder+<>c+<<BuildPipeline>b__8_0>d.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
MyWebApp.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
await _next.Invoke(httpContext);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()
始终显示 Tenent 中间件而不是发生错误的页面行
MyWebApp.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
await _next.Invoke(httpContext);
有没有办法让堆栈跟踪指向发生错误的页面?
谢谢。
更新
感谢陶老师的回答,我想出了一个可能的原因。
问题出在 Startup.cs,在 COnfigureServices:
services.AddMvc(options =>
{
options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipeline)));
});
和 LocalizationPipeline:
public class LocalizationPipeline
{
public void Configure(IApplicationBuilder appBuilder, RequestLocalizationOptions options)
{
appBuilder.UseRequestLocalization(options);
}
}
当我删除那条线时,轨迹看起来像:
DivideByZeroException: Attempted to divide by zero.
MyWebApp.Web.Controllers.TestController.Index() in TestController.cs
+
var c = b / a;
lambda_method(Closure , object , Object[] )
Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(object target, Object[] parameters)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__12.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextActionFilterAsync>d__10.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeInnerFilterAsync>d__14.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
MyWebApp.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
await _next.Invoke(httpContext);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()
知道为什么要从跟踪中删除所有信息吗?任何可能的解决方案?
这个问题是由MiddlewareFilterBuilder
引起的。
对于 Asp.Net Core 2.0
项目,Microsoft.AspNetCore.Mvc.Core
是 Version 2.0.4
有这个错误。 Version 2.1.0
通过添加 resourceExecutedContext.ExceptionDispatchInfo?.Throw();.
解决方案:
尝试使用来自 Nuget window 的 Version 2.1.2
安装 Microsoft.AspNetCore.Mvc.Core
。
解决方法
MiddlewareFilterBuilder
的自定义实现。
- 添加MiddlewareFilter
- 添加MiddlewareFilterAttribute
- 添加MiddlewareFilterBuilder
- 添加MiddlewareFilterBuilderStartupFilter
修改
Startup.cs
ConfigureService
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipeline))); }); services.AddSingleton<RequestLocalizationOptions>(); services.AddSingleton<MiddlewareFilterBuilder>(); services.Add(ServiceDescriptor.Singleton<IStartupFilter, MiddlewareFilterBuilderStartupFilter>()); }