即使env.IsDevelopment为true,Asp.Net Core也不会显示开发人员异常页面

时间:2018-08-02 05:06:07

标签: asp.net-core exception-handling

我的启动代码如下:

if (env.IsDevelopment())
{
    app.UseBrowserLink();
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}

一个断点确认env.IsDevelopment路由已执行。

但是,当我遇到异常时,执行/ Home / Error Action(由该Action方法的代码中的断点确认),并返回相应的视图: Not the Developer Exception Page

即使Startup中的断点确认我已经在开发环境中,怎么会告诉我切换到开发环境?

编辑

好吧,没关系...问题似乎在IdentityServer4的代码中更深了。这就是异常的来源,并且最终以某种方式忽略了DeveloperExceptionPage设置。在我自己的代码中其他地方抛出的其他异常正确返回了DeveloperExceptionPage

3 个答案:

答案 0 :(得分:1)

这是一篇旧帖子,但我会针对相关用例发布我们的解决方案,其中 IdentityServer 内部发生的错误绕过了启动中的异常处理。这对我们来说是个问题,因为我们想在错误页面上显示与错误对应的关联 ID。

我们最终得到了一个中间件,用于检查是否有重定向到错误页面,如果有,我们将关联 ID 附加到查询参数中。

我们最终得到的中间件如下所示:

/// <summary>
/// This middleware is necessary to handle exceptions that are handled internally
/// by IdentityServer, since IdentityServer uses their own error page redirection,
/// instead of using the exceptionhandling specified in Startup.
/// 
/// If this middleware is omitted, the CorrelationId will not be transfered correctly
/// to the error page.
/// </summary>
public class IdSrvCorrelationIdTransferMiddleware
{
    public static string QueryParamKey = "correlationId";

    private readonly RequestDelegate _next;
    private readonly ILogger<IdSrvCorrelationIdTransferMiddleware> _logger;
    private readonly ILoggingDataProvider _loggingDataProvider;

    public IdSrvCorrelationIdTransferMiddleware(
        RequestDelegate next, 
        ILogger<IdSrvCorrelationIdTransferMiddleware> logger, 
        ILoggingDataProvider loggingDataProvider)
    {
        _next = next;
        _logger = logger;
        _loggingDataProvider = loggingDataProvider;
    }

    public async Task Invoke(HttpContext context)
    {
        await _next.Invoke(context);

        /* If response is a redirect, and the destination is the error page, 
         * we must manually set CorrelationID. Since it's a redirect, we cannot
         * use headers to transfer CorrelationID, and instead we use query params.
         */
        if (context.Response.StatusCode == 302)
        {
            var location = context.Response.GetTypedHeaders().Location;

            if (location.IsAbsoluteUri && location.AbsolutePath == "/Home/Error".ToLower())
            {
                var correlationId = _loggingDataProvider.GetCorrelationId();

                if (correlationId.HasValue)
                {
                    var uriBuilder = new UriBuilder(location);
                    var query = HttpUtility.ParseQueryString(uriBuilder.Query);
                    query[QueryParamKey] = correlationId.Value.ToString("D");
                    uriBuilder.Query = query.ToString();
                    context.Response.Headers[HeaderNames.Location] = uriBuilder.ToString();
                }

                _logger.LogInformation($"Redirecting user to {context.Response.GetTypedHeaders().Location}");
            }
        }
    }
}

注意:ILoggingDataProvider 是我们存储关联 ID 的内部对象。

然后我们在错误页面上阅读:

/// <summary>
/// Shows the error page
/// </summary>
public async Task<IActionResult> Error()
{
    var vm = new ErrorViewModel
    {
        CorrelationId = GetCorrelationId()
    };

    return View("Error", vm);
}

/// <summary>
/// Gets the correlation ID from query parameter if available, otherwise get from logging data provider
/// </summary>
/// <returns></returns>
private Guid? GetCorrelationId()
{
    if (HttpContext.Request.Query.ContainsKey(IdSrvCorrelationIdTransferMiddleware.QueryParamKey))
    {
        if (Guid.TryParse(HttpContext.Request.Query[IdSrvCorrelationIdTransferMiddleware.QueryParamKey], out Guid correlationId))
        {
            return correlationId;
        }
    }

    return _loggingDataProvider.GetCorrelationId();
}

答案 1 :(得分:0)

您是否将UseDeveloperExceptionPage()放在其他任何中间件的前面?

根据中间件管道模型,必须首先注册DeveloperExceptionPage中间件以捕获异常。

答案 2 :(得分:0)

  1. ASPNETCORE_ENVIRONMENT
  2. 第一个UseDeveloperExceptionPage应该注册到中间件管道,并且它会为抛出的任何错误显示开发人员友好的错误信息页面。请确保正在为您期望的页面筹集资金。 例如如果您请求任何特定页面,请添加“ throw new Exception(“ Error!”);“到特定的MVC控制器,然后查看页面。 HTH