ASP.NET Core Razor Pages에서 상태 코드 페이지 구성

http 의 404 에러등에 대응한 페이지를 구성하고 싶다고 하는 경우의 대응입니다.

Startup.Configure 메서드에서
app.UseStatusCodePages();

를 추가하여 404 등의 상태 코드 페이지를 제공할 수있는 것 같습니다.

보통은
app.UseStaticFiles();

앞에 쓰면 좋을 것 같습니다.

실제로 확인해 보겠습니다.
확실히 다음과 같은 페이지가 표시되었습니다.



하지만 너무 똑같지 않습니다.

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을 지정해 봅니다.



이 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을 넣으십시오.



어디에서 오류가 발생했는지 알 수 있습니다.

좋은 웹페이지 즐겨찾기