LoginSignup
2

More than 3 years have passed since last update.

ASP.NET Core Razor Pagesで状態コードページを構成する

Last updated at Posted at 2020-01-08

http の 404エラーなどに対応したページを構成したいという場合の対応です。

Startup.Configureメソッドで、

app.UseStatusCodePages();

を追加することで、 404などのステータスコードのページを提供することができるようです。

通常は、

app.UseStaticFiles();

の前に、書けば良いようです。

実際に確かめてみます。
確かに、以下のようなページが表示されました。

スクリーンショット 2020-01-05 18.04.31.png

でも、あまりにもそっけないです。

UseStatusCodePagesWithRedirects メソッド

調べたら、UseStatusCodePagesWithRedirectsというメソッドがあるようです。

app.UseStatusCodePagesWithRedirects("/error/{0}");

とすれば、指定したページにリダイレクトされるようです。
すでに、Error.cshtml Error.cshtml.csがデフォルトで作成されているので、これで実行してみます。

あれ、だめです。「リダイレクトが繰り返し行われました。」とエラーになってしまいます。
OnGetメソッドが呼び出されません。

ブラウザのURLは、

https://localhost:5001/error/404

となるので、想定したURLにリダイレクトはされているようです。

でもソースコードをよくみたら、OnGetAsyncメソッドには、StatusCodeを受け取る引数がありません。

ああ、Error.cshtmlは、アプリケーション内での例外に対応するエラーページなのですね。

ということで、以下のように書き換えます。

app.UseStatusCodePagesWithRedirects("/statuserror/{0}");

statuserrorページも作成します。
Pagesフォルダーの下に、

StatusError.cshtmlとStatusError.cshtml.cs ファイルを以下のように作成します。

StatusError.cshtml.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace RazorPagesMovie.Pages
{
    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public class StatusErrorModel : PageModel
    {
        public int HttpStatusCode { get; set; }

        public IActionResult OnGet(int code)
        {
            HttpStatusCode = code;
            return Page();
        }
    }
}

StatusError.cshtml
@page "{code}"
@model RazorPagesMovie.Pages.StatusErrorModel
@{
    ViewData["Title"] = "StatusError";
}
<h3>エラーが発生しました。</h3>

<div>StatusCode : @Model.HttpStatusCode</div>

実行して、存在しないURLを指定してみます。

スクリーンショット 2020-01-05 18.09.41.png

このcshtmlは、固定でメッセージを表示していますが、実際は、ステータスコードに対応するメッセージを表示するなどの対応が必要になると思います。

ASP.NET MVCの時は、Http Statusコードに対応したページを表示するには、Web.configで面倒な記述が必要だったんですが、そういったことなく実現できるのはありがたいです。

UseStatusCodePagesWithReExecute メソッド

UseStatusCodePagesWithReExecuteというメソッドもあるようです。

  app.UseStatusCodePagesWithReExecute("/statuserror","?code={0}");

こちらは、リダイレクトせずに同じURLのまま、エラーページが表示されます。

こちらに、変更してみます。

エラーの発生したURLを表示する

ページに表示された内容だけだと、どのURLでエラーが発生したのかがわかりません。まあ、ユーザにとってはあまり気にするところではありませんが、開発者側からするとこれが分かったほうが何かと便利です。

ということで、ページモデルを変更します。

using Microsoft.AspNetCore.Diagnostics;


   public class StatusErrorModel : PageModel
    {
        public int HttpStatusCode { get; set; }

        public string ErrorPath { get; set; }

        public IActionResult OnGet(int code)
        {
            HttpStatusCode = code;
            var feature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
            if (feature != null)
            {
                ErrorPath = feature.OriginalPathBase
                    + feature.OriginalPath + feature.OriginalQueryString;
            }
            return Page();
        }
    }

これで、どのURLを要求したのかがわかります。
Viewも ErrorPath を表示するように書き換えます。

@page
@model RazorPagesMovie.Pages.StatusErrorModel
@{
    ViewData["Title"] = "StatusError";
}
<h3>エラーが発生しました。</h3>

<div>StatusCode : @Model.HttpStatusCode</div>
<div>URL : @Model.ErrorPath</div>

実行してみます。
ブラウザのアドレスバーで、存在しないURLを入れてみます。

スクリーンショット 2020-01-05 18.47.48.png

どこでエラーが発生したのかがわかるようになりました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2