【问题标题】:asp.net core 2 exception not showing where the issue isasp.net core 2 异常未显示问题所在
【发布时间】:2019-01-25 03:23:50
【问题描述】:

我有一个 asp.net coree 2 web 应用程序。我使用中间件过滤器,因为它是一个多租户应用程序。

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

有没有办法让堆栈跟踪指向发生错误的页面?

谢谢。

更新

感谢Tao的回答,我想出了一个可能的原因。

问题出在 Startup.cs 中,在 CConfigureServices 中:

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()

知道为什么要从跟踪中删除所有信息吗?任何可能的解决方案?

【问题讨论】:

  • 是的,TenantMiddleware 有一个合适的构造函数。我已经更新了我的问题。中间件也工作正常。我唯一的问题是当我在控制器中有错误或查看跟踪总是引用中间件时,所以我看不到错误在哪里......
  • 重现问题的详细步骤是什么?我用新的 asp.net 核心项目做了一个测试,创建TenantMiddleware 并在HomeController 中抛出异常,我可以在右边的行中得到异常CoreApp.Controllers.HomeController.Index() in HomeController.cs, line 23
  • 感谢Tao,你让我知道了可以做什么。问题出在 Startup.cs 的 ConfigureServices 中。 services.AddMvc(options => { options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipeline))); });如果我删除该行,它会起作用并显示错误....我已经用所有代码更新了我的问题
  • 这是一个错误,检查一下MiddlewareFilter exception not meaningful #6596

标签: asp.net-core-2.0 stack-trace asp.net-core-middleware


【解决方案1】:

这个问题是由MiddlewareFilterBuilder引起的。

对于Asp.Net Core 2.0 项目,Microsoft.AspNetCore.Mvc.CoreVersion 2.0.4,它有这个错误。 Version 2.1.0 已通过添加 resourceExecutedContext.ExceptionDispatchInfo?.Throw();. 修复此问题

Source.

解决办法:

尝试从 Nuget 窗口安装 Microsoft.AspNetCore.Mvc.CoreVersion 2.1.2

解决方法

MiddlewareFilterBuilder 的自定义实现。

  1. 添加MiddlewareFilter
  2. 添加MiddlewareFilterAttribute
  3. 添加MiddlewareFilterBuilder
  4. 添加MiddlewareFilterBuilderStartupFilter
  5. 修改Startup.csConfigureService

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

【讨论】:

  • 谢谢,这是我读了很多关于它的想象。问题是 MySQL 在 2.1 中还不能正常工作......
  • @JohnMathison 如果是这样,您可以尝试使用workaround 来实现您自己的MiddlewareFilterBuilder。 github问题中缺少一些代码链接,您可以查看我的答案中的源代码。
  • 谢谢Tao,但是其中一个链接坏了,你没有一个如何创建自己的MiddlewareFilterBuilder的例子吗?
  • 非常感谢,它有效,至少目前没有副作用。为了工作,我需要删除的唯一行是 services.AddSingleton();因为我已经创建了自己的翻译系统,并且我从数据库中加载了页面,所以用户可以更改他们的页面名称......但是现在我确实有错误的跟踪,这很棒。
  • @JohnMathison 还有一点,我不确定你是否通过安装Microsoft.AspNetCore.Mvc.Core进行测试,它不会影响EF Core库,也就是说它不会影响mysql功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多