ASP.NET Coreにカスタムエラーページが表示されます-拡張版

7281 ワード

以前のブログASP.NET Coreにカスタムエラーページを表示する方法は、プロジェクト内でハードコーディングで実現され、複数のプロジェクトがある場合、異なるプロジェクト間の重複コードをもたらし、望ましくない.
このブログではmiddlewareで実装し、独立したプロジェクトでNuGetパッケージとして公開します.プロジェクトで使用する場合はNuGetパッケージをインストールし、StartupのConfigure()メソッドに次のコードを追加します.
app.UseCustomErrorPages();

CustomErrorPagesMiddlewareの実装コードは次のとおりです.
public class CustomErrorPagesMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public CustomErrorPagesMiddleware(
        RequestDelegate next,
        ILoggerFactory loggerFactory)
    {
        _next = next;
        _logger = loggerFactory.CreateLogger<CustomErrorPagesMiddleware>();
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(0, ex, "An unhandled exception has occurred while executing the request");

            if (context.Response.HasStarted)
            {
                _logger.LogWarning("The response has already started, the error page middleware will not be executed.");
                throw;
            }
            try
            {
                context.Response.Clear();
                context.Response.StatusCode = 500;
                return;
            }
            catch (Exception ex2)
            {
                _logger.LogError(0, ex2, "An exception was thrown attempting to display the error page.");
            }
            throw;
        }
        finally
        {
            var statusCode = context.Response.StatusCode;
            if (statusCode == 404 || statusCode == 500)
            {
                await ErrorPage.ResponseAsync(context.Response, statusCode);
            }
        }
    }
}

ErrorPageの実装コードは以下の通りである.
public static class ErrorPage
{
    public static async Task ResponseAsync(HttpResponse response, int statusCode)
    {
        if (statusCode == 404)
        {
            await response.WriteAsync(Page404);
        }
        else if (statusCode == 500)
        {
            await response.WriteAsync(Page500);
        }
    }

    private static string Page404 => @"html...";

    private static string Page500 => @"html...";
}

CustomErrorPagesExtensionsの実装コードは次のとおりです.
public static class CustomErrorPagesExtensions
{
    public static IApplicationBuilder UseCustomErrorPages(this IApplicationBuilder app)
    {
        if (app == null)
        {
            throw new ArgumentNullException(nameof(app));
        }

        return app.UseMiddleware<CustomErrorPagesMiddleware>();
    }
}

コード参照:
1)CustomErrorPagesMiddleware.cs
2)DeveloperExceptionPageMiddleware.cs