ASP.NET CoreはMiddlewareを使用してCustom Error Page機能をシミュレートする

11394 ワード

一、シーンの使用


従来のASP.NET MVCでは、Actionが放出する異常をどのように処理するかを具体的に指定するためにHandleErrorAttributeの特性を用いることができる.あるアクションにHandleErrorAttributeプロパティが設定されている限り、デフォルトでは、このアクションが例外を投げ出すとMVCは、~/Views/Sharedディレクトリの下にあるErrorビューを表示します.
エラーページをカスタマイズする目的は、エラー/例外が発生したときに、プログラムがより良い表示体験を得ることができるようにすることです.Errorビューでエラーが発生する場合があります.この場合ASP.NET/MVCにはデフォルトのエラーページ(黄底赤字)が表示されますが、このような状況を避けるために、私たちはWebにいます.configファイルのcustomErrorsセクションでエラーページをカスタマイズし、カスタムエラー処理を有効にします.
 

  
    "true" />
    "On" defaultRedirect="DefaultError">
      "401" redirect="Http401Error"/>
      "403" redirect="Http403Error"/>
      "404" redirect="Http404Error"/>
      "500" redirect="Http500Error"/>
    
  

二、NET Core実装


ASPを使いたいならNET CoreのミドルウェアシミュレーションCustom Error Page機能は、まず構成から始めます.みんな知ってるNET Coreではプロファイルシステムが大きく変化し、デフォルトはJson形式のファイルで格納されています.もちろん、プロファイルは他のタイプでも構いません.ここでは深く検討しません.Jsonプロファイルをめぐって実現します.
"ErrorPages": {
  "401": "/Error/Http401Page",
  "403": "/Error/Http403Page",
  "404": "/Error/Http404Page",
  "500": "/Error/Http500Page"
}

プロファイルから読み込まれた情報を格納するために、Startupクラスで2つの変数を定義します.
public IConfigurationRoot Configuration { get; }

internal static IDictionary<int, string> ErrorPages { get; } = new Dictionary<int, string>();

プロファイルに定義されているErrorPagesノードは、必要なHttp状態符号化を格納し、使用されたエラーページアドレスを含み、StartupクラスのErrorPages変数でKey/Valueの形式で読み出します.
次に、JSONプロファイルからErrorPagesに情報を読み込みます.
var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();

Configuration = builder.Build();

foreach (var c in Configuration.GetSection("ErrorPages").GetChildren())
{
    var key = Convert.ToInt32(c.Key);
    if (!ErrorPages.Keys.Contains(key))
    {
        ErrorPages.Add(key, c.Value);
    }
}

今日の主役を使ってASPを作成します.NET CoreのMiddlewareは、Custom Error Page機能を実現するために使用されます.
public class CustomErrorPagesMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

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

    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 (Startup.ErrorPages.Keys.Contains(statusCode))
            {
                context.Request.Path = Startup.ErrorPages[statusCode];
                await _next(context);
            }
        }
    }

これで、ResponseのStatusCodeに応答して構成された特定のページへのジャンプが完了します.
もちろん最後に、このミドルウェアに拡張方法を追加します.ASP.NET CoreではIApplictionBuilderのために多くの拡張方法が作成されていますが、実際にはその名前のように、コンストラクタモデルである必要があります.
拡張方法は次のとおりです.
 
public static class BuilderExtensions
{
    public static IApplicationBuilder UseCustomErrorPages(this IApplicationBuilder app)
    {
        return app.UseMiddleware();
    }
}

 
最後にStartupクラスのConfigureメソッドにカスタムエラーの拡張子を追加します.
app.UseCustomErrorPages();

三、ソースコード


もしあなたが文の中のコードに興味があれば、私のGithubにこの例のソースコードを見てもいいです.https://github.com/maxzhang1985/CustomErrorPages
 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
オープンソース:
YOYOFxは、HTTPベースのWebサービスを構築するための軽量級のサポートである.NET Framework 、.NET CORE、Monoプラットフォーム.
学習の態度に基づいて、この車輪を作ったのも、各フレームワークの原理と少しをもっとよく理解するためで、みんなともっと交流したいと思っています.
  GitHub:https://github.com/maxzhang1985/YOYOFxスターの下で、一緒に交流することを歓迎します. .NET CoreとYOYOFxの交流群:214741894
本文が役に立つと思ったら、「お勧め」をクリックしてください.ありがとうございます.