我的启动代码如下:
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
一个断点确认env.IsDevelopment路由已执行。
但是,当我遇到异常时,执行/ Home / Error Action(由该Action方法的代码中的断点确认),并返回相应的视图:
即使Startup中的断点确认我已经在开发环境中,怎么会告诉我切换到开发环境?
编辑
好吧,没关系...问题似乎在IdentityServer4的代码中更深了。这就是异常的来源,并且最终以某种方式忽略了DeveloperExceptionPage设置。在我自己的代码中其他地方抛出的其他异常正确返回了DeveloperExceptionPage
答案 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)